Infrared4Arduino  1.0.6
boarddefs.h
Go to the documentation of this file.
1 //******************************************************************************
2 // IRremote
3 // Version 2.0.1 June, 2015
4 // Copyright 2009 Ken Shirriff
5 // For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
6 
7 // This file contains all board specific information. It was previously contained within
8 // IRremoteInt.h
9 
10 // Modified by Paul Stoffregen <paul@pjrc.com> to support other boards and timers
11 //
12 // Interrupt code based on NECIRrcv by Joe Knapp
13 // http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556
14 // Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/
15 //
16 // JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
17 // Whynter A/C ARC-110WD added by Francesco Meschia
18 //******************************************************************************
19 
20 #pragma once
21 
22 // Define some defaults, that some boards may like to override
23 // (This is to avoid negative logic, ! DONT_... is just awkward.)
24 
25 // This board has/needs the avr/interrupt.h
26 #define HAS_AVR_INTERRUPT_H
27 
28 // Define if sending is supported
29 #define SENDING_SUPPORTED
30 
31 // If defined, a standard enableIRIn function will be define.
32 // Undefine for boards supplying their own.
33 #define USE_DEFAULT_ENABLE_IR_IN
34 
35 // Duty cycle in percent for sent signals. Presently takes effect only with USE_SOFT_CARRIER
36 #define DUTY_CYCLE 50
37 
38 // If USE_SOFT_CARRIER, this amount (in micro seconds) is subtracted from the
39 // on-time of the pulses.
40 #define PULSE_CORRECTION 3
41 
42 // digitalWrite is supposed to be slow. If this is an issue, define faster,
43 // board-dependent versions of these macros SENDPIN_ON(pin) and SENDPIN_OFF(pin).
44 // Portable, possibly slow, default definitions are given at the end of this file.
45 // If defining new versions, feel free to ignore the pin argument if it
46 // is not configurable on the current board.
47 
48 //------------------------------------------------------------------------------
49 // Defines for blinking the LED
50 //
51 
52 #if defined(CORE_LED0_PIN)
53 # define BLINKLED CORE_LED0_PIN
54 # define BLINKLED_ON() (digitalWrite(CORE_LED0_PIN, HIGH))
55 # define BLINKLED_OFF() (digitalWrite(CORE_LED0_PIN, LOW))
56 
57 #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
58 # define BLINKLED 13
59 # define BLINKLED_ON() (PORTB |= B10000000)
60 # define BLINKLED_OFF() (PORTB &= B01111111)
61 
62 #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
63 # define BLINKLED 0
64 # define BLINKLED_ON() (PORTD |= B00000001)
65 # define BLINKLED_OFF() (PORTD &= B11111110)
66 
67 #elif defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD)
68 # define BLINKLED LED_BUILTIN
69 # define BLINKLED_ON() (digitalWrite(LED_BUILTIN, HIGH))
70 # define BLINKLED_OFF() (digitalWrite(LED_BUILTIN, LOW))
71 
72 # define USE_SOFT_CARRIER
73  // Define to use spin wait instead of delayMicros()
74 # define USE_SPIN_WAIT
75 # undef USE_DEFAULT_ENABLE_IR_IN
76 
77  // The default pin used used for sending.
78 # define SEND_PIN 9
79 
80 #elif defined(ESP32)
81  // No system LED on ESP32, disable blinking by NOT defining BLINKLED
82 
83  // avr/interrupt.h is not present
84 # undef HAS_AVR_INTERRUPT_H
85 
86  // Sending not implemented
87 # undef SENDING_SUPPORTED#
88 
89  // Supply own enbleIRIn
90 # undef USE_DEFAULT_ENABLE_IR_IN
91 
92 #elif defined(ESP8266)
93 
94 // avr/interrupt.h is not present
95 # undef HAS_AVR_INTERRUPT_H
96 
97 # define USE_SOFT_CARRIER
98 
99  // Supply own enbleIRIn
100 # undef USE_DEFAULT_ENABLE_IR_IN
101 
102  // The default pin used used for sending.
103 # define SEND_PIN 4 // pin 4 = D2 on board
104 
105 #else
106 # define BLINKLED 13
107 # define BLINKLED_ON() (PORTB |= B00100000)
108 # define BLINKLED_OFF() (PORTB &= B11011111)
109 #endif
110 
111 //------------------------------------------------------------------------------
112 // CPU Frequency
113 //
114 #ifdef F_CPU
115 # define SYSCLOCK F_CPU // main Arduino clock
116 #else
117 # define SYSCLOCK 16000000 // main Arduino clock
118 #endif
119 
120 // microseconds per clock interrupt tick
121 #define USECPERTICK 50
122 
123 //------------------------------------------------------------------------------
124 // Define which timer to use
125 //
126 // Uncomment the timer you wish to use on your board.
127 // If you are using another library which uses timer2, you have options to
128 // switch IRremote to use a different timer.
129 //
130 
131 // Arduino Mega
132 #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
133  //#define IR_USE_TIMER1 // tx = pin 11
134  #define IR_USE_TIMER2 // tx = pin 9
135  //#define IR_USE_TIMER3 // tx = pin 5
136  //#define IR_USE_TIMER4 // tx = pin 6
137  //#define IR_USE_TIMER5 // tx = pin 46
138 
139 // Teensy 1.0
140 #elif defined(__AVR_AT90USB162__)
141  #define IR_USE_TIMER1 // tx = pin 17
142 
143 // Teensy 2.0
144 #elif defined(__AVR_ATmega32U4__)
145  //#define IR_USE_TIMER1 // tx = pin 14
146  //#define IR_USE_TIMER3 // tx = pin 9
147  #define IR_USE_TIMER4_HS // tx = pin 10
148 
149 // Teensy 3.0 / Teensy 3.1
150 #elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
151  #define IR_USE_TIMER_CMT // tx = pin 5
152 
153 // Teensy-LC
154 #elif defined(__MKL26Z64__)
155  #define IR_USE_TIMER_TPM1 // tx = pin 16
156 
157 // Teensy++ 1.0 & 2.0
158 #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
159  //#define IR_USE_TIMER1 // tx = pin 25
160  #define IR_USE_TIMER2 // tx = pin 1
161  //#define IR_USE_TIMER3 // tx = pin 16
162 
163 // MightyCore - ATmega1284
164 #elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)
165  //#define IR_USE_TIMER1 // tx = pin 13
166  #define IR_USE_TIMER2 // tx = pin 14
167  //#define IR_USE_TIMER3 // tx = pin 6
168 
169 // MightyCore - ATmega164, ATmega324, ATmega644
170 #elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \
171 || defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \
172 || defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \
173 || defined(__AVR_ATmega164P__)
174  //#define IR_USE_TIMER1 // tx = pin 13
175  #define IR_USE_TIMER2 // tx = pin 14
176 
177 //MegaCore - ATmega64, ATmega128
178 #elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__)
179  #define IR_USE_TIMER1 // tx = pin 13
180 
181 // MightyCore - ATmega8535, ATmega16, ATmega32
182 #elif defined(__AVR_ATmega8535__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__)
183  #define IR_USE_TIMER1 // tx = pin 13
184 
185 // Atmega8
186 #elif defined(__AVR_ATmega8__)
187  #define IR_USE_TIMER1 // tx = pin 9
188 
189 // ATtiny84
190 #elif defined(__AVR_ATtiny84__)
191  #define IR_USE_TIMER1 // tx = pin 6
192 
193 //ATtiny85
194 #elif defined(__AVR_ATtiny85__)
195  #define IR_USE_TIMER_TINY0 // tx = pin 1
196 
197 #elif defined(ESP32)
198  #define IR_TIMER_USE_ESP32
199 
200 #elif defined(ESP8266)
201 
202 #elif defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD)
203  #define TIMER_PRESCALER_DIV 64
204 
205 #else
206 // Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, Nano, etc
207 // ATmega48, ATmega88, ATmega168, ATmega328
208  //#define IR_USE_TIMER1 // tx = pin 9
209  #define IR_USE_TIMER2 // tx = pin 3
210 
211 #endif
212 
213 //------------------------------------------------------------------------------
214 // Defines for Timer
215 
216 //---------------------------------------------------------
217 // Timer2 (8 bits)
218 //
219 #if defined(IR_USE_TIMER2)
220 
221 #define TIMER_RESET
222 #define TIMER_ENABLE_PWM (TCCR2A |= _BV(COM2B1))
223 #define TIMER_DISABLE_PWM (TCCR2A &= ~(_BV(COM2B1)))
224 #define TIMER_ENABLE_INTR (TIMSK2 = _BV(OCIE2A))
225 #define TIMER_DISABLE_INTR (TIMSK2 = 0)
226 #define TIMER_INTR_NAME TIMER2_COMPA_vect
227 
228 #define TIMER_CONFIG_KHZ(val) ({ \
229  const uint8_t pwmval = SYSCLOCK / 2000 / (val); \
230  TCCR2A = _BV(WGM20); \
231  TCCR2B = _BV(WGM22) | _BV(CS20); \
232  OCR2A = pwmval; \
233  OCR2B = pwmval / 3; \
234 })
235 
236 #define TIMER_COUNT_TOP (SYSCLOCK * USECPERTICK / 1000000)
237 
238 //-----------------
239 #if (TIMER_COUNT_TOP < 256)
240 # define TIMER_CONFIG_NORMAL() ({ \
241  TCCR2A = _BV(WGM21); \
242  TCCR2B = _BV(CS20); \
243  OCR2A = TIMER_COUNT_TOP; \
244  TCNT2 = 0; \
245  })
246 #else
247 # define TIMER_CONFIG_NORMAL() ({ \
248  TCCR2A = _BV(WGM21); \
249  TCCR2B = _BV(CS21); \
250  OCR2A = TIMER_COUNT_TOP / 8; \
251  TCNT2 = 0; \
252  })
253 #endif
254 
255 //-----------------
256 #if defined(CORE_OC2B_PIN)
257 # define SEND_PIN CORE_OC2B_PIN // Teensy
258 #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
259 # define SEND_PIN 9 // Arduino Mega
260 #elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \
261 || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \
262 || defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \
263 || defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \
264 || defined(__AVR_ATmega164P__)
265 # define SEND_PIN 14 // MightyCore
266 #else
267 # define SEND_PIN 3 // Arduino Duemilanove, Diecimila, LilyPad, etc
268 #endif // ATmega48, ATmega88, ATmega168, ATmega328
269 
270 //---------------------------------------------------------
271 // Timer1 (16 bits)
272 //
273 #elif defined(IR_USE_TIMER1)
274 
275 #define TIMER_RESET
276 #define TIMER_ENABLE_PWM (TCCR1A |= _BV(COM1A1))
277 #define TIMER_DISABLE_PWM (TCCR1A &= ~(_BV(COM1A1)))
278 
279 //-----------------
280 #if defined(__AVR_ATmega8__) || defined(__AVR_ATmega8535__) \
281 || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) \
282 || defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__)
283 # define TIMER_ENABLE_INTR (TIMSK |= _BV(OCIE1A))
284 # define TIMER_DISABLE_INTR (TIMSK &= ~_BV(OCIE1A))
285 #else
286 # define TIMER_ENABLE_INTR (TIMSK1 = _BV(OCIE1A))
287 # define TIMER_DISABLE_INTR (TIMSK1 = 0)
288 #endif
289 
290 //-----------------
291 #define TIMER_INTR_NAME TIMER1_COMPA_vect
292 
293 #define TIMER_CONFIG_KHZ(val) ({ \
294  const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
295  TCCR1A = _BV(WGM11); \
296  TCCR1B = _BV(WGM13) | _BV(CS10); \
297  ICR1 = pwmval; \
298  OCR1A = pwmval / 3; \
299 })
300 
301 #define TIMER_CONFIG_NORMAL() ({ \
302  TCCR1A = 0; \
303  TCCR1B = _BV(WGM12) | _BV(CS10); \
304  OCR1A = SYSCLOCK * USECPERTICK / 1000000; \
305  TCNT1 = 0; \
306 })
307 
308 //-----------------
309 #if defined(CORE_OC1A_PIN)
310 # define SEND_PIN CORE_OC1A_PIN // Teensy
311 #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
312 # define SEND_PIN 11 // Arduino Mega
313 #elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__)
314 # define SEND_PIN 13 // MegaCore
315 #elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \
316 || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \
317 || defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \
318 || defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \
319 || defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \
320 || defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__)
321 # define SEND_PIN 13 // MightyCore
322 #elif defined(__AVR_ATtiny84__)
323 # define SEND_PIN 6
324 #else
325 # define SEND_PIN 9 // Arduino Duemilanove, Diecimila, LilyPad, etc
326 #endif // ATmega48, ATmega88, ATmega168, ATmega328
327 
328 //---------------------------------------------------------
329 // Timer3 (16 bits)
330 //
331 #elif defined(IR_USE_TIMER3)
332 
333 #define TIMER_RESET
334 #define TIMER_ENABLE_PWM (TCCR3A |= _BV(COM3A1))
335 #define TIMER_DISABLE_PWM (TCCR3A &= ~(_BV(COM3A1)))
336 #define TIMER_ENABLE_INTR (TIMSK3 = _BV(OCIE3A))
337 #define TIMER_DISABLE_INTR (TIMSK3 = 0)
338 #define TIMER_INTR_NAME TIMER3_COMPA_vect
339 
340 #define TIMER_CONFIG_KHZ(val) ({ \
341  const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
342  TCCR3A = _BV(WGM31); \
343  TCCR3B = _BV(WGM33) | _BV(CS30); \
344  ICR3 = pwmval; \
345  OCR3A = pwmval / 3; \
346 })
347 
348 #define TIMER_CONFIG_NORMAL() ({ \
349  TCCR3A = 0; \
350  TCCR3B = _BV(WGM32) | _BV(CS30); \
351  OCR3A = SYSCLOCK * USECPERTICK / 1000000; \
352  TCNT3 = 0; \
353 })
354 
355 //-----------------
356 #if defined(CORE_OC3A_PIN)
357 # define SEND_PIN CORE_OC3A_PIN // Teensy
358 #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
359 # define SEND_PIN 5 // Arduino Mega
360 #elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)
361 # define SEND_PIN 6 // MightyCore
362 #else
363 # error "Please add OC3A pin number here\n"
364 #endif
365 
366 //---------------------------------------------------------
367 // Timer4 (10 bits, high speed option)
368 //
369 #elif defined(IR_USE_TIMER4_HS)
370 
371 #define TIMER_RESET
372 #define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1))
373 #define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1)))
374 #define TIMER_ENABLE_INTR (TIMSK4 = _BV(TOIE4))
375 #define TIMER_DISABLE_INTR (TIMSK4 = 0)
376 #define TIMER_INTR_NAME TIMER4_OVF_vect
377 
378 #define TIMER_CONFIG_KHZ(val) ({ \
379  const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
380  TCCR4A = (1<<PWM4A); \
381  TCCR4B = _BV(CS40); \
382  TCCR4C = 0; \
383  TCCR4D = (1<<WGM40); \
384  TCCR4E = 0; \
385  TC4H = pwmval >> 8; \
386  OCR4C = pwmval; \
387  TC4H = (pwmval / 3) >> 8; \
388  OCR4A = (pwmval / 3) & 255; \
389 })
390 
391 #define TIMER_CONFIG_NORMAL() ({ \
392  TCCR4A = 0; \
393  TCCR4B = _BV(CS40); \
394  TCCR4C = 0; \
395  TCCR4D = 0; \
396  TCCR4E = 0; \
397  TC4H = (SYSCLOCK * USECPERTICK / 1000000) >> 8; \
398  OCR4C = (SYSCLOCK * USECPERTICK / 1000000) & 255; \
399  TC4H = 0; \
400  TCNT4 = 0; \
401 })
402 
403 //-----------------
404 #if defined(CORE_OC4A_PIN)
405 # define SEND_PIN CORE_OC4A_PIN // Teensy
406 #elif defined(__AVR_ATmega32U4__)
407 # define SEND_PIN 13 // Leonardo
408 #else
409 # error "Please add OC4A pin number here\n"
410 #endif
411 
412 //---------------------------------------------------------
413 // Timer4 (16 bits)
414 //
415 #elif defined(IR_USE_TIMER4)
416 
417 #define TIMER_RESET
418 #define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1))
419 #define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1)))
420 #define TIMER_ENABLE_INTR (TIMSK4 = _BV(OCIE4A))
421 #define TIMER_DISABLE_INTR (TIMSK4 = 0)
422 #define TIMER_INTR_NAME TIMER4_COMPA_vect
423 
424 #define TIMER_CONFIG_KHZ(val) ({ \
425  const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
426  TCCR4A = _BV(WGM41); \
427  TCCR4B = _BV(WGM43) | _BV(CS40); \
428  ICR4 = pwmval; \
429  OCR4A = pwmval / 3; \
430 })
431 
432 #define TIMER_CONFIG_NORMAL() ({ \
433  TCCR4A = 0; \
434  TCCR4B = _BV(WGM42) | _BV(CS40); \
435  OCR4A = SYSCLOCK * USECPERTICK / 1000000; \
436  TCNT4 = 0; \
437 })
438 
439 //-----------------
440 #if defined(CORE_OC4A_PIN)
441 # define SEND_PIN CORE_OC4A_PIN
442 #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
443 # define SEND_PIN 6 // Arduino Mega
444 #else
445 # error "Please add OC4A pin number here\n"
446 #endif
447 
448 //---------------------------------------------------------
449 // Timer5 (16 bits)
450 //
451 #elif defined(IR_USE_TIMER5)
452 
453 #define TIMER_RESET
454 #define TIMER_ENABLE_PWM (TCCR5A |= _BV(COM5A1))
455 #define TIMER_DISABLE_PWM (TCCR5A &= ~(_BV(COM5A1)))
456 #define TIMER_ENABLE_INTR (TIMSK5 = _BV(OCIE5A))
457 #define TIMER_DISABLE_INTR (TIMSK5 = 0)
458 #define TIMER_INTR_NAME TIMER5_COMPA_vect
459 
460 #define TIMER_CONFIG_KHZ(val) ({ \
461  const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
462  TCCR5A = _BV(WGM51); \
463  TCCR5B = _BV(WGM53) | _BV(CS50); \
464  ICR5 = pwmval; \
465  OCR5A = pwmval / 3; \
466 })
467 
468 #define TIMER_CONFIG_NORMAL() ({ \
469  TCCR5A = 0; \
470  TCCR5B = _BV(WGM52) | _BV(CS50); \
471  OCR5A = SYSCLOCK * USECPERTICK / 1000000; \
472  TCNT5 = 0; \
473 })
474 
475 //-----------------
476 #if defined(CORE_OC5A_PIN)
477 # define SEND_PIN CORE_OC5A_PIN
478 #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
479 # define SEND_PIN 46 // Arduino Mega
480 #else
481 # error "Please add OC5A pin number here\n"
482 #endif
483 
484 //---------------------------------------------------------
485 // Special carrier modulator timer
486 //
487 #elif defined(IR_USE_TIMER_CMT)
488 
489 #define TIMER_RESET ({ \
490  uint8_t tmp __attribute__((unused)) = CMT_MSC; \
491  CMT_CMD2 = 30; \
492 })
493 
494 #define TIMER_ENABLE_PWM do { \
495  CORE_PIN5_CONFIG = PORT_PCR_MUX(2) | PORT_PCR_DSE | PORT_PCR_SRE; \
496 } while(0)
497 
498 #define TIMER_DISABLE_PWM do { \
499  CORE_PIN5_CONFIG = PORT_PCR_MUX(1) | PORT_PCR_DSE | PORT_PCR_SRE; \
500 } while(0)
501 
502 #define TIMER_ENABLE_INTR NVIC_ENABLE_IRQ(IRQ_CMT)
503 #define TIMER_DISABLE_INTR NVIC_DISABLE_IRQ(IRQ_CMT)
504 #define TIMER_INTR_NAME cmt_isr
505 
506 //-----------------
507 #ifdef ISR
508 # undef ISR
509 #endif
510 #define ISR(f) void f(void)
511 
512 //-----------------
513 #define CMT_PPS_DIV ((F_BUS + 7999999) / 8000000)
514 #if F_BUS < 8000000
515 #error IRremote requires at least 8 MHz on Teensy 3.x
516 #endif
517 
518 //-----------------
519 #define TIMER_CONFIG_KHZ(val) ({ \
520  SIM_SCGC4 |= SIM_SCGC4_CMT; \
521  SIM_SOPT2 |= SIM_SOPT2_PTD7PAD; \
522  CMT_PPS = CMT_PPS_DIV - 1; \
523  CMT_CGH1 = ((F_BUS / CMT_PPS_DIV / 3000) + ((val)/2)) / (val); \
524  CMT_CGL1 = ((F_BUS / CMT_PPS_DIV / 1500) + ((val)/2)) / (val); \
525  CMT_CMD1 = 0; \
526  CMT_CMD2 = 30; \
527  CMT_CMD3 = 0; \
528  CMT_CMD4 = 0; \
529  CMT_OC = 0x60; \
530  CMT_MSC = 0x01; \
531 })
532 
533 #define TIMER_CONFIG_NORMAL() ({ \
534  SIM_SCGC4 |= SIM_SCGC4_CMT; \
535  CMT_PPS = CMT_PPS_DIV - 1; \
536  CMT_CGH1 = 1; \
537  CMT_CGL1 = 1; \
538  CMT_CMD1 = 0; \
539  CMT_CMD2 = 30; \
540  CMT_CMD3 = 0; \
541  CMT_CMD4 = (F_BUS / 160000 + CMT_PPS_DIV / 2) / CMT_PPS_DIV - 31; \
542  CMT_OC = 0; \
543  CMT_MSC = 0x03; \
544 })
545 
546 #define SEND_PIN 5
547 
548 // defines for TPM1 timer on Teensy-LC
549 #elif defined(IR_USE_TIMER_TPM1)
550 #define TIMER_RESET FTM1_SC |= FTM_SC_TOF;
551 #define TIMER_ENABLE_PWM CORE_PIN16_CONFIG = PORT_PCR_MUX(3)|PORT_PCR_DSE|PORT_PCR_SRE
552 #define TIMER_DISABLE_PWM CORE_PIN16_CONFIG = PORT_PCR_MUX(1)|PORT_PCR_SRE
553 #define TIMER_ENABLE_INTR NVIC_ENABLE_IRQ(IRQ_FTM1)
554 #define TIMER_DISABLE_INTR NVIC_DISABLE_IRQ(IRQ_FTM1)
555 #define TIMER_INTR_NAME ftm1_isr
556 #ifdef ISR
557 #undef ISR
558 #endif
559 #define ISR(f) void f(void)
560 #define TIMER_CONFIG_KHZ(val) ({ \
561  SIM_SCGC6 |= SIM_SCGC6_TPM1; \
562  FTM1_SC = 0; \
563  FTM1_CNT = 0; \
564  FTM1_MOD = (F_PLL/2000) / val - 1; \
565  FTM1_C0V = (F_PLL/6000) / val - 1; \
566  FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0); \
567 })
568 #define TIMER_CONFIG_NORMAL() ({ \
569  SIM_SCGC6 |= SIM_SCGC6_TPM1; \
570  FTM1_SC = 0; \
571  FTM1_CNT = 0; \
572  FTM1_MOD = (F_PLL/40000) - 1; \
573  FTM1_C0V = 0; \
574  FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0) | FTM_SC_TOF | FTM_SC_TOIE; \
575 })
576 #define SEND_PIN 16
577 
578 // defines for timer_tiny0 (8 bits)
579 #elif defined(IR_USE_TIMER_TINY0)
580 #define TIMER_RESET
581 #define TIMER_ENABLE_PWM (TCCR0A |= _BV(COM0B1))
582 #define TIMER_DISABLE_PWM (TCCR0A &= ~(_BV(COM0B1)))
583 #define TIMER_ENABLE_INTR (TIMSK |= _BV(OCIE0A))
584 #define TIMER_DISABLE_INTR (TIMSK &= ~(_BV(OCIE0A)))
585 #define TIMER_INTR_NAME TIMER0_COMPA_vect
586 #define TIMER_CONFIG_KHZ(val) ({ \
587  const uint8_t pwmval = SYSCLOCK / 2000 / (val); \
588  TCCR0A = _BV(WGM00); \
589  TCCR0B = _BV(WGM02) | _BV(CS00); \
590  OCR0A = pwmval; \
591  OCR0B = pwmval / 3; \
592 })
593 #define TIMER_COUNT_TOP (SYSCLOCK * USECPERTICK / 1000000)
594 #if (TIMER_COUNT_TOP < 256)
595 #define TIMER_CONFIG_NORMAL() ({ \
596  TCCR0A = _BV(WGM01); \
597  TCCR0B = _BV(CS00); \
598  OCR0A = TIMER_COUNT_TOP; \
599  TCNT0 = 0; \
600 })
601 #else
602 #define TIMER_CONFIG_NORMAL() ({ \
603  TCCR0A = _BV(WGM01); \
604  TCCR0B = _BV(CS01); \
605  OCR0A = TIMER_COUNT_TOP / 8; \
606  TCNT0 = 0; \
607 })
608 #endif
609 
610 #define SEND_PIN 1 /* ATtiny85 */
611 
612 //---------------------------------------------------------
613 // ESP32 (ESP8266 should likely be added here too)
614 //
615 
616 // ESP32 has it own timer API and does not use these macros, but to avoid ifdef'ing
617 // them out in the common code, they are defined to no-op. This allows the code to compile
618 // (which it wouldn't otherwise) but irsend will not work until ESP32 specific code is written
619 // for that -- merlin
620 // As a warning, sending timing specific code from an ESP32 can be challenging if you need 100%
621 // reliability because the arduino code may be interrupted and cause your sent waveform to be the
622 // wrong length. This is specifically an issue for neopixels which require 800Khz resolution.
623 // IR may just work as is with the common code since it's lower frequency, but if not, the other
624 // way to do this on ESP32 is using the RMT built in driver like in this incomplete library below
625 // https://github.com/ExploreEmbedded/ESP32_RMT
626 #elif defined(IR_TIMER_USE_ESP32)
627 
628 #define TIMER_RESET
629 
630 #ifdef ISR
631 # undef ISR
632 #endif
633 #define ISR(f) void IRTimer()
634 
635 #elif defined(ESP8266)
636 
637 #define TIMER_RESET
638 
639 //#define TIMER_CONFIG_NORMAL()
640 //#define TIMER_ENABLE_INTR
641 #define TIMER_DISABLE_PWM
642 #define TIMER_DISABLE_INTR
643 #define TIMER_CONFIG_KHZ(khz)
644 
645 #ifdef ISR
646 # undef ISR
647 #endif
648 
649 #elif defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD)
650 // use timer 3 hardcoded at this time
651 
652 #define TIMER_RESET
653 #define TIMER_ENABLE_PWM // Not presently used
654 #define TIMER_DISABLE_PWM
655 #define TIMER_ENABLE_INTR NVIC_EnableIRQ(TC3_IRQn) // Not presently used
656 #define TIMER_DISABLE_INTR NVIC_DisableIRQ(TC3_IRQn)
657 #define TIMER_INTR_NAME TC3_Handler // Not presently used
658 #define TIMER_CONFIG_KHZ(f)
659 
660 #ifdef ISR
661 # undef ISR
662 #endif
663 #define ISR(f) void irs()
664 
665 //---------------------------------------------------------
666 // Unknown Timer
667 //
668 #else
669 # error "Internal code configuration error, no known IR_USE_TIMER# defined\n"
670 #endif
671 
672 // Provide default definitions, portable but possibly slower than necessary.
673 #ifndef SENDPIN_ON
674 #define SENDPIN_ON(pin) digitalWrite(pin, HIGH)
675 #endif
676 
677 #ifndef SENDPIN_OFF
678 #define SENDPIN_OFF(pin) digitalWrite(pin, LOW)
679 #endif