IRremote
IRremoteBoardDefs.h
Go to the documentation of this file.
1 
9 // IRremote
10 // Version 2.0.1 June, 2015
11 // Copyright 2009 Ken Shirriff
12 // For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
13 // Modified by Paul Stoffregen <paul@pjrc.com> to support other boards and timers
14 //
15 // Interrupt code based on NECIRrcv by Joe Knapp
16 // http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556
17 // Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/
18 //
19 // JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
20 // Whynter A/C ARC-110WD added by Francesco Meschia
21 // Sparkfun Pro Micro support by Alastair McCormack
22 //******************************************************************************
23 #ifndef IRremoteBoardDefs_h
24 #define IRremoteBoardDefs_h
25 
26 // Define some defaults, that some boards may like to override
27 // (This is to avoid negative logic, ! DONT_... is just awkward.)
28 
32 #define HAS_AVR_INTERRUPT_H
33 
38 #define USE_DEFAULT_ENABLE_IR_IN
39 
43 #define SENDING_SUPPORTED
44 
49 #define USE_DEFAULT_ENABLE_IR_OUT
50 
54 #if ! defined(DUTY_CYCLE)
55 #define DUTY_CYCLE 30 // 30 saves power and is compatible to the old existing code
56 #endif
57 
62 #define PULSE_CORRECTION 3
63 
64 //------------------------------------------------------------------------------
65 // This first #ifdef statement contains defines for blinking the LED,
66 // as well as all other board specific information, with the exception of
67 // timers and the sending pin (IR_SEND_PIN).
68 
69 #ifdef DOXYGEN
70 
74 #define BLINKLED LED_BUILTIN
75 
79 #define BLINKLED_ON() digitalWrite(BLINKLED, HIGH)
80 
84 #define BLINKLED_OFF() digitalWrite(BLINKLED, HIGH)
85 
89 #define USE_NO_CARRIER
90 
94 #define USE_SOFT_CARRIER
95 
99 #define USE_SPIN_WAIT
100 
101 #elif ! defined(ARDUINO)
102 // Assume that we compile a test version, to be executed on the host, not on a board.
103 
104 // Do not define anything.
105 
106 #undef HAS_AVR_INTERRUPT_H
107 
108 #elif defined(CORE_LED0_PIN)
109 #define BLINKLED CORE_LED0_PIN
110 #define BLINKLED_ON() (digitalWrite(CORE_LED0_PIN, HIGH))
111 #define BLINKLED_OFF() (digitalWrite(CORE_LED0_PIN, LOW))
112 
113 // Arduino Uno, Nano etc (previously default clause)
114 #elif defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega32U4__)
115 #define BLINKLED LED_BUILTIN
116 #define BLINKLED_ON() (PORTB |= B00100000)
117 #define BLINKLED_OFF() (PORTB &= B11011111)
118 
119 #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
120 #define BLINKLED 13
121 #define BLINKLED_ON() (PORTB |= B10000000)
122 #define BLINKLED_OFF() (PORTB &= B01111111)
123 
124 #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
125 #define BLINKLED 0
126 #define BLINKLED_ON() (PORTD |= B00000001)
127 #define BLINKLED_OFF() (PORTD &= B11111110)
128 
129 // Nano Every, Uno WiFi Rev2
130 #elif defined(__AVR_ATmega4809__)
131 #define BLINKLED LED_BUILTIN
132 #define BLINKLED_ON() (digitalWrite(BLINKLED, HIGH))
133 #define BLINKLED_OFF() (digitalWrite(BLINKLED, LOW))
134 
135 #elif defined(ARDUINO_ARCH_SAMD)
136 #define BLINKLED LED_BUILTIN
137 #define BLINKLED_ON() (digitalWrite(LED_BUILTIN, HIGH))
138 #define BLINKLED_OFF() (digitalWrite(LED_BUILTIN, LOW))
139 
140 #define USE_SOFT_CARRIER
141 // Define to use spin wait instead of delayMicros()
142 //#define USE_SPIN_WAIT
143 #undef USE_DEFAULT_ENABLE_IR_IN
144 
145 #elif defined(ESP32)
146 // No system LED on ESP32, disable blinking by NOT defining BLINKLED
147 
148 // avr/interrupt.h is not present
149 #undef HAS_AVR_INTERRUPT_H
150 
151 // Supply own enbleIRIn
152 #undef USE_DEFAULT_ENABLE_IR_IN
153 #undef USE_DEFAULT_ENABLE_IR_OUT
154 
155 #else
156 #warning No blinking definition found. Check IRremoteBoardDefs.h.
157 #ifdef LED_BUILTIN
158 #define BLINKLED LED_BUILTIN
159 #define BLINKLED_ON() digitalWrite(BLINKLED, HIGH)
160 #define BLINKLED_OFF() digitalWrite(BLINKLED, LOW)
161 #endif
162 #endif
163 
164 //------------------------------------------------------------------------------
165 // microseconds per clock interrupt tick
166 #define USECPERTICK 50
167 
168 //------------------------------------------------------------------------------
169 // Define which timer to use
170 //
171 // Uncomment the timer you wish to use on your board.
172 // If you are using another library which uses timer2, you have options to
173 // switch IRremote to use a different timer.
174 //
175 
176 #ifndef ARDUINO
177 // Assume that we compile a test version, to be executed on the host,
178 // not on a board.
179 
180 // Do not define any timer.
181 
182 // Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, Nano, etc
183 // ATmega48, ATmega88, ATmega168, ATmega328
184 #elif defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) // old default clause
185 # if !defined(IR_USE_TIMER1) && !defined(IR_USE_TIMER2)
186 //#define IR_USE_TIMER1 // tx = pin 9
187 #define IR_USE_TIMER2 // tx = pin 3
188 # endif
189 
190 // Sparkfun Pro Micro
191 #elif defined(ARDUINO_AVR_PROMICRO)
192 # if !defined(IR_USE_TIMER1) && !defined(IR_USE_TIMER3) && !defined(IR_USE_TIMER4_HS)
193 //#define IR_USE_TIMER1 // tx = pin 9
194 #define IR_USE_TIMER3 // tx = pin 5
195 //#define IR_USE_TIMER4_HS // tx = pin 13
196 # endif
197 
198 // Leonardo
199 #elif defined(__AVR_ATmega32U4__) && ! defined(TEENSYDUINO)
200 # if !defined(IR_USE_TIMER1) && !defined(IR_USE_TIMER3) && !defined(IR_USE_TIMER4_HS)
201 //#define IR_USE_TIMER1 // tx = pin 9
202 #define IR_USE_TIMER3 // tx = pin 5
203 //#define IR_USE_TIMER4_HS // tx = pin 13
204 # endif
205 
206 // Arduino Mega
207 #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
208 # if !defined(IR_USE_TIMER1) && !defined(IR_USE_TIMER2) && !defined(IR_USE_TIMER3) && !defined(IR_USE_TIMER4) && !defined(IR_USE_TIMER5)
209 //#define IR_USE_TIMER1 // tx = pin 11
210 #define IR_USE_TIMER2 // tx = pin 9
211 //#define IR_USE_TIMER3 // tx = pin 5
212 //#define IR_USE_TIMER4 // tx = pin 6
213 //#define IR_USE_TIMER5 // tx = pin 46
214 # endif
215 
216 // Nano Every, Uno WiFi Rev2
217 #elif defined(__AVR_ATmega4809__)
218 # if !defined(IR_USE_TIMER_4809_1) && !defined(IR_USE_TIMER_4809_2)
219 #define IR_USE_TIMER_4809_1 // tx = pin 24
220 //#define IR_USE_TIMER_4809_2 // TODO tx = pin 21
221 # endif
222 
223 // Teensy 1.0
224 #elif defined(__AVR_AT90USB162__)
225 # if !defined(IR_USE_TIMER1)
226 #define IR_USE_TIMER1 // tx = pin 17
227 # endif
228 
229 // Teensy 2.0
230 #elif defined(__AVR_ATmega32U4__) && defined(TEENSYDUINO)
231 # if !defined(IR_USE_TIMER1) && !defined(IR_USE_TIMER3) && !defined(IR_USE_TIMER4_HS)
232 //#define IR_USE_TIMER1 // tx = pin 14 (Teensy 2.0 - physical pin: B5)
233 #define IR_USE_TIMER3 // tx = pin 9 (Teensy 2.0 - physical pin: C6)
234 //#define IR_USE_TIMER4_HS // tx = pin 10 (Teensy 2.0 - physical pin: C7)
235 # endif
236 
237 // Teensy 3.0 / Teensy 3.1
238 #elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
239 # if !defined(IR_USE_TIMER_CMT)
240 #define IR_USE_TIMER_CMT // tx = pin 5
241 # endif
242 
243 // Teensy-LC
244 #elif defined(__MKL26Z64__)
245 # if !defined(IR_USE_TIMER_TPM1)
246 #define IR_USE_TIMER_TPM1 // tx = pin 16
247 # endif
248 
249 // Teensy++ 1.0 & 2.0
250 #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
251 # if !defined(IR_USE_TIMER1) && !defined(IR_USE_TIMER2) && !defined(IR_USE_TIMER3)
252 //#define IR_USE_TIMER1 // tx = pin 25
253 #define IR_USE_TIMER2 // tx = pin 1
254 //#define IR_USE_TIMER3 // tx = pin 16
255 # endif
256 
257 // MightyCore - ATmega1284
258 #elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)
259 # if !defined(IR_USE_TIMER1) && !defined(IR_USE_TIMER2) && !defined(IR_USE_TIMER3)
260 //#define IR_USE_TIMER1 // tx = pin 13
261 #define IR_USE_TIMER2 // tx = pin 14
262 //#define IR_USE_TIMER3 // tx = pin 6
263 # endif
264 
265 // MightyCore - ATmega164, ATmega324, ATmega644
266 #elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \
267 || defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \
268 || defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \
269 || defined(__AVR_ATmega164P__)
270 # if !defined(IR_USE_TIMER1) && !defined(IR_USE_TIMER2)
271 //#define IR_USE_TIMER1 // tx = pin 13
272 #define IR_USE_TIMER2 // tx = pin 14
273 # endif
274 
275 //MegaCore - ATmega64, ATmega128
276 #elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__)
277 # if !defined(IR_USE_TIMER1)
278  #define IR_USE_TIMER1 // tx = pin 13
279 # endif
280 
281 // MightyCore - ATmega8535, ATmega16, ATmega32
282 #elif defined(__AVR_ATmega8535__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__)
283 # if !defined(IR_USE_TIMER1)
284 #define IR_USE_TIMER1 // tx = pin 13
285 # endif
286 
287 // Atmega8
288 #elif defined(__AVR_ATmega8__)
289 # if !defined(IR_USE_TIMER1)
290 #define IR_USE_TIMER1 // tx = pin 9
291 # endif
292 
293 // ATtiny84
294 #elif defined(__AVR_ATtiny84__)
295 # if !defined(IR_USE_TIMER1)
296 #define IR_USE_TIMER1 // tx = pin 6
297 # endif
298 
299 //ATtiny85
300 #elif defined(__AVR_ATtiny85__)
301 # if !defined(IR_USE_TIMER_TINY0)
302 #define IR_USE_TIMER_TINY0 // tx = pin 1
303 # endif
304 
305 #elif defined(ESP32)
306 # if !defined(IR_TIMER_USE_ESP32)
307 #define IR_TIMER_USE_ESP32
308 # endif
309 
310 #elif defined(ARDUINO_ARCH_SAMD)
311 #define TIMER_PRESCALER_DIV 64
312 
313 #else
314 // Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, Nano, etc
315 // ATmega48, ATmega88, ATmega168, ATmega328
316 //#define IR_USE_TIMER1 // tx = pin 9
317 #error Board could not be identified from pre-processor symbols. Please extend IRremoteBoardDefs.h.
318 #endif
319 
320 // Provide default definitions, portable but possibly slower than necessary.
321 // digitalWrite is supposed to be slow. If this is an issue, define faster,
322 // board-dependent versions of these macros SENDPIN_ON(pin) and SENDPIN_OFF(pin).
323 // Portable, possibly slow, default definitions are given at the end of this file.
324 // If defining new versions, feel free to ignore the pin argument if it
325 // is not configurable on the current board.
326 
327 #ifndef SENDPIN_ON
328 
329 #define SENDPIN_ON(pin) digitalWrite(pin, HIGH)
330 #endif
331 
332 #ifndef SENDPIN_OFF
333 
336 #define SENDPIN_OFF(pin) digitalWrite(pin, LOW)
337 #endif
338 
339 //------------------------------------------------------------------------------
340 // CPU Frequency
341 //
342 #if !defined(SYSCLOCK) && defined(ARDUINO) // allow for processor specific code to define SYSCLOCK
343 #ifndef F_CPU
344 #error SYSCLOCK cannot be determined. Define it for your board in IRremoteBoardDefs.h.
345 #endif // ! F_CPU
346 
349 #define SYSCLOCK F_CPU // main Arduino clock
350 #endif // ! SYSCLOCK
351 
352 //------------------------------------------------------------------------------
353 // Defines for Timer
354 
355 //---------------------------------------------------------
356 #ifdef DOXYGEN
357 
362 #define IR_SEND_PIN
363 
367 #define ISR
368 
369 #elif ! defined(ARDUINO)
370 // Assume that we compile a test version, to be executed on the host,
371 // not on a board.
372 // Do nothing.
373 #ifdef ISR
374 #undef ISR
375 #endif
376 #define ISR(f) void do_not_use__(void)
377 #define TIMER_RESET
378 
379 //---------------------------------------------------------
380 // Timer2 (8 bits)
381 //
382 #elif defined(IR_USE_TIMER2)
383 
384 #define TIMER_RESET
385 #define TIMER_ENABLE_PWM (TCCR2A |= _BV(COM2B1))
386 #define TIMER_DISABLE_PWM (TCCR2A &= ~(_BV(COM2B1)))
387 #define TIMER_ENABLE_INTR (TIMSK2 = _BV(OCIE2A))
388 #define TIMER_DISABLE_INTR (TIMSK2 = 0)
389 #define TIMER_INTR_NAME TIMER2_COMPA_vect
390 
391 #define TIMER_CONFIG_KHZ(val) ({ \
392 const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
393 TCCR2A = _BV(WGM20); \
394 TCCR2B = _BV(WGM22) | _BV(CS20); \
395 OCR2A = pwmval; \
396 OCR2B = pwmval * DUTY_CYCLE / 100; \
397 })
398 
399 #define TIMER_COUNT_TOP (SYSCLOCK * USECPERTICK / 1000000)
400 
401 //-----------------
402 #if (TIMER_COUNT_TOP < 256)
403 #define TIMER_CONFIG_NORMAL() ({ \
404 TCCR2A = _BV(WGM21); \
405 TCCR2B = _BV(CS20); \
406 OCR2A = TIMER_COUNT_TOP; \
407 TCNT2 = 0; \
408 })
409 #else
410 #define TIMER_CONFIG_NORMAL() ({ \
411 TCCR2A = _BV(WGM21); \
412 TCCR2B = _BV(CS21); \
413 OCR2A = TIMER_COUNT_TOP / 8; \
414 TCNT2 = 0; \
415 })
416 #endif
417 
418 //-----------------
419 #if defined(CORE_OC2B_PIN)
420 #define IR_SEND_PIN CORE_OC2B_PIN // Teensy
421 
422 #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
423 #define IR_SEND_PIN 9 // Arduino Mega
424 
425 #elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \
426 || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \
427 || defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \
428 || defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \
429 || defined(__AVR_ATmega164P__)
430 #define IR_SEND_PIN 14 // MightyCore, MegaCore
431 
432 #else
433 #define IR_SEND_PIN 3 // Arduino Duemilanove, Diecimila, LilyPad, etc
434 #endif // defined(CORE_OC2B_PIN)
435 
436 //---------------------------------------------------------
437 // Timer1 (16 bits)
438 //
439 #elif defined(IR_USE_TIMER1)
440 
441 #define TIMER_RESET
442 #define TIMER_ENABLE_PWM (TCCR1A |= _BV(COM1A1))
443 #define TIMER_DISABLE_PWM (TCCR1A &= ~(_BV(COM1A1)))
444 
445 //-----------------
446 #if defined(__AVR_ATmega8__) || defined(__AVR_ATmega8535__) \
447 || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) \
448 || defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__)
449 #define TIMER_ENABLE_INTR (TIMSK |= _BV(OCIE1A))
450 #define TIMER_DISABLE_INTR (TIMSK &= ~_BV(OCIE1A))
451 #else
452 #define TIMER_ENABLE_INTR (TIMSK1 = _BV(OCIE1A))
453 #define TIMER_DISABLE_INTR (TIMSK1 = 0)
454 #endif
455 
456 //-----------------
457 #define TIMER_INTR_NAME TIMER1_COMPA_vect
458 
459 #define TIMER_CONFIG_KHZ(val) ({ \
460 const uint32_t pwmval = SYSCLOCK / 2000 / (val); \
461 TCCR1A = _BV(WGM11); \
462 TCCR1B = _BV(WGM13) | _BV(CS10); \
463 ICR1 = pwmval; \
464 OCR1A = pwmval * DUTY_CYCLE / 100; \
465 })
466 
467 #define TIMER_CONFIG_NORMAL() ({ \
468 TCCR1A = 0; \
469 TCCR1B = _BV(WGM12) | _BV(CS10); \
470 OCR1A = SYSCLOCK * USECPERTICK / 1000000; \
471 TCNT1 = 0; \
472 })
473 
474 //-----------------
475 #if defined(CORE_OC1A_PIN)
476 #define IR_SEND_PIN CORE_OC1A_PIN // Teensy
477 
478 #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
479 #define IR_SEND_PIN 11 // Arduino Mega
480 
481 #elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \
482 || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \
483 || defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \
484 || defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \
485 || defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \
486 || defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__) \
487 || defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__)
488 #define IR_SEND_PIN 13 // MightyCore, MegaCore
489 
490 #elif defined(__AVR_ATtiny84__)
491 # define IR_SEND_PIN 6
492 
493 #else
494 #define IR_SEND_PIN 9 // Arduino Duemilanove, Diecimila, LilyPad, Sparkfun Pro Micro, Leonardo etc.
495 #endif // defined(CORE_OC1A_PIN)
496 
497 //---------------------------------------------------------
498 // Timer3 (16 bits)
499 //
500 #elif defined(IR_USE_TIMER3)
501 
502 #define TIMER_RESET
503 #define TIMER_ENABLE_PWM (TCCR3A |= _BV(COM3A1))
504 #define TIMER_DISABLE_PWM (TCCR3A &= ~(_BV(COM3A1)))
505 #define TIMER_ENABLE_INTR (TIMSK3 = _BV(OCIE3A))
506 #define TIMER_DISABLE_INTR (TIMSK3 = 0)
507 #define TIMER_INTR_NAME TIMER3_COMPA_vect
508 
509 #define TIMER_CONFIG_KHZ(val) ({ \
510  const uint32_t pwmval = SYSCLOCK / 2000 / (val); \
511  TCCR3A = _BV(WGM31); \
512  TCCR3B = _BV(WGM33) | _BV(CS30); \
513  ICR3 = pwmval; \
514  OCR3A = pwmval * DUTY_CYCLE / 100; \
515 })
516 
517 #define TIMER_CONFIG_NORMAL() ({ \
518  TCCR3A = 0; \
519  TCCR3B = _BV(WGM32) | _BV(CS30); \
520  OCR3A = SYSCLOCK * USECPERTICK / 1000000; \
521  TCNT3 = 0; \
522 })
523 
524 //-----------------
525 #if defined(CORE_OC3A_PIN)
526 #define IR_SEND_PIN CORE_OC3A_PIN // Teensy
527 
528 #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) \
529 || defined(__AVR_ATmega32U4__) || defined(ARDUINO_AVR_PROMICRO)
530 #define IR_SEND_PIN 5 // Arduino Mega, Arduino Leonardo, Sparkfun Pro Micro
531 
532 #elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)
533 #define IR_SEND_PIN 6 // MightyCore, MegaCore
534 
535 #else
536 #error "Please add OC3A pin number here\n"
537 #endif
538 
539 //---------------------------------------------------------
540 // Timer4 (10 bits, high speed option)
541 //
542 #elif defined(IR_USE_TIMER4_HS)
543 
544 #define TIMER_RESET
545 #if defined(ARDUINO_AVR_PROMICRO) // Sparkfun Pro Micro
546 #define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A0)) // Use complimentary O̅C̅4̅A̅ output on pin 5
547 #define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A0))) // (Pro Micro does not map PC7 (32/ICP3/CLK0/OC4A)
548  // of ATmega32U4 )
549 #else
550 #define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1))
551 #define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1)))
552 #endif
553 #define TIMER_ENABLE_INTR (TIMSK4 = _BV(TOIE4))
554 #define TIMER_DISABLE_INTR (TIMSK4 = 0)
555 #define TIMER_INTR_NAME TIMER4_OVF_vect
556 
557 #define TIMER_CONFIG_KHZ(val) ({ \
558 const uint32_t pwmval = SYSCLOCK / 2000 / (val); \
559 TCCR4A = (1<<PWM4A); \
560 TCCR4B = _BV(CS40); \
561 TCCR4C = 0; \
562 TCCR4D = (1<<WGM40); \
563 TCCR4E = 0; \
564 TC4H = pwmval >> 8; \
565 OCR4C = pwmval; \
566 TC4H = (pwmval * DUTY_CYCLE / 100) >> 8; \
567 OCR4A = (pwmval * DUTY_CYCLE / 100) & 255; \
568 })
569 
570 #define TIMER_CONFIG_NORMAL() ({ \
571 TCCR4A = 0; \
572 TCCR4B = _BV(CS40); \
573 TCCR4C = 0; \
574 TCCR4D = 0; \
575 TCCR4E = 0; \
576 TC4H = (SYSCLOCK * USECPERTICK / 1000000) >> 8; \
577 OCR4C = (SYSCLOCK * USECPERTICK / 1000000) & 255; \
578 TC4H = 0; \
579 TCNT4 = 0; \
580 })
581 
582 //-----------------
583 #if defined(CORE_OC4A_PIN)
584 #define IR_SEND_PIN CORE_OC4A_PIN // Teensy
585 #elif defined(ARDUINO_AVR_PROMICRO)
586 # define IR_SEND_PIN 5 // Sparkfun Pro Micro
587 #elif defined(__AVR_ATmega32U4__)
588 #define IR_SEND_PIN 13 // Leonardo
589 #else
590 #error "Please add OC4A pin number here\n"
591 #endif
592 
593 //---------------------------------------------------------
594 // Timer4 (16 bits)
595 //
596 #elif defined(IR_USE_TIMER4)
597 
598 #define TIMER_RESET
599 #define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1))
600 #define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1)))
601 #define TIMER_ENABLE_INTR (TIMSK4 = _BV(OCIE4A))
602 #define TIMER_DISABLE_INTR (TIMSK4 = 0)
603 #define TIMER_INTR_NAME TIMER4_COMPA_vect
604 
605 #define TIMER_CONFIG_KHZ(val) ({ \
606  const uint32_t pwmval = SYSCLOCK / 2000 / (val); \
607  TCCR4A = _BV(WGM41); \
608  TCCR4B = _BV(WGM43) | _BV(CS40); \
609  ICR4 = pwmval; \
610  OCR4A = pwmval * DUTY_CYCLE / 100; \
611 })
612 
613 #define TIMER_CONFIG_NORMAL() ({ \
614  TCCR4A = 0; \
615  TCCR4B = _BV(WGM42) | _BV(CS40); \
616  OCR4A = SYSCLOCK * USECPERTICK / 1000000; \
617  TCNT4 = 0; \
618 })
619 
620 //-----------------
621 #if defined(CORE_OC4A_PIN)
622 #define IR_SEND_PIN CORE_OC4A_PIN
623 #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
624 #define IR_SEND_PIN 6 // Arduino Mega
625 #else
626 #error "Please add OC4A pin number here\n"
627 #endif
628 
629 //---------------------------------------------------------
630 // Timer5 (16 bits)
631 //
632 #elif defined(IR_USE_TIMER5)
633 
634 #define TIMER_RESET
635 #define TIMER_ENABLE_PWM (TCCR5A |= _BV(COM5A1))
636 #define TIMER_DISABLE_PWM (TCCR5A &= ~(_BV(COM5A1)))
637 #define TIMER_ENABLE_INTR (TIMSK5 = _BV(OCIE5A))
638 #define TIMER_DISABLE_INTR (TIMSK5 = 0)
639 #define TIMER_INTR_NAME TIMER5_COMPA_vect
640 
641 #define TIMER_CONFIG_KHZ(val) ({ \
642  const uint32_t pwmval = SYSCLOCK / 2000 / (val); \
643  TCCR5A = _BV(WGM51); \
644  TCCR5B = _BV(WGM53) | _BV(CS50); \
645  ICR5 = pwmval; \
646  OCR5A = pwmval * DUTY_CYCLE / 100; \
647 })
648 
649 #define TIMER_CONFIG_NORMAL() ({ \
650  TCCR5A = 0; \
651  TCCR5B = _BV(WGM52) | _BV(CS50); \
652  OCR5A = SYSCLOCK * USECPERTICK / 1000000; \
653  TCNT5 = 0; \
654 })
655 
656 //-----------------
657 #if defined(CORE_OC5A_PIN)
658 #define IR_SEND_PIN CORE_OC5A_PIN
659 #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
660 #define IR_SEND_PIN 46 // Arduino Mega
661 #else
662 #error "Please add OC5A pin number here\n"
663 #endif
664 
665 //---------------------------------------------------------
666 // Special carrier modulator timer
667 //
668 #elif defined(IR_USE_TIMER_CMT)
669 
670 #define TIMER_RESET ({ \
671 uint8_t tmp __attribute__((unused)) = CMT_MSC; \
672 CMT_CMD2 = 30; \
673 })
674 
675 #define TIMER_ENABLE_PWM do { \
676 CORE_PIN5_CONFIG = PORT_PCR_MUX(2) | PORT_PCR_DSE | PORT_PCR_SRE; \
677 } while(0)
678 
679 #define TIMER_DISABLE_PWM do { \
680 CORE_PIN5_CONFIG = PORT_PCR_MUX(1) | PORT_PCR_DSE | PORT_PCR_SRE; \
681 } while(0)
682 
683 #define TIMER_ENABLE_INTR NVIC_ENABLE_IRQ(IRQ_CMT)
684 #define TIMER_DISABLE_INTR NVIC_DISABLE_IRQ(IRQ_CMT)
685 #define TIMER_INTR_NAME cmt_isr
686 
687 //-----------------
688 #ifdef ISR
689 #undef ISR
690 #endif
691 #define ISR(f) void f(void)
692 
693 //-----------------
694 #define CMT_PPS_DIV ((F_BUS + 7999999) / 8000000)
695 #if F_BUS < 8000000
696 #error IRremote requires at least 8 MHz on Teensy 3.x
697 #endif
698 
699 //-----------------
700 #define TIMER_CONFIG_KHZ(val) ({ \
701 SIM_SCGC4 |= SIM_SCGC4_CMT; \
702 SIM_SOPT2 |= SIM_SOPT2_PTD7PAD; \
703 CMT_PPS = CMT_PPS_DIV - 1; \
704 CMT_CGH1 = ((F_BUS / CMT_PPS_DIV / 3000) + ((val)/2)) / (val); \
705 CMT_CGL1 = ((F_BUS / CMT_PPS_DIV / 1500) + ((val)/2)) / (val); \
706 CMT_CMD1 = 0; \
707 CMT_CMD2 = 30; \
708 CMT_CMD3 = 0; \
709 CMT_CMD4 = 0; \
710 CMT_OC = 0x60; \
711 CMT_MSC = 0x01; \
712 })
713 
714 #define TIMER_CONFIG_NORMAL() ({ \
715 SIM_SCGC4 |= SIM_SCGC4_CMT; \
716 CMT_PPS = CMT_PPS_DIV - 1; \
717 CMT_CGH1 = 1; \
718 CMT_CGL1 = 1; \
719 CMT_CMD1 = 0; \
720 CMT_CMD2 = 30; \
721 CMT_CMD3 = 0; \
722 CMT_CMD4 = (F_BUS / 160000 + CMT_PPS_DIV / 2) / CMT_PPS_DIV - 31; \
723 CMT_OC = 0; \
724 CMT_MSC = 0x03; \
725 })
726 
727 #define IR_SEND_PIN 5
728 
729 // defines for TPM1 timer on Teensy-LC
730 #elif defined(IR_USE_TIMER_TPM1)
731 #define TIMER_RESET FTM1_SC |= FTM_SC_TOF;
732 #define TIMER_ENABLE_PWM CORE_PIN16_CONFIG = PORT_PCR_MUX(3)|PORT_PCR_DSE|PORT_PCR_SRE
733 #define TIMER_DISABLE_PWM CORE_PIN16_CONFIG = PORT_PCR_MUX(1)|PORT_PCR_SRE
734 #define TIMER_ENABLE_INTR NVIC_ENABLE_IRQ(IRQ_FTM1)
735 #define TIMER_DISABLE_INTR NVIC_DISABLE_IRQ(IRQ_FTM1)
736 #define TIMER_INTR_NAME ftm1_isr
737 #ifdef ISR
738 #undef ISR
739 #endif
740 #define ISR(f) void f(void)
741 #define TIMER_CONFIG_KHZ(val) ({ \
742 SIM_SCGC6 |= SIM_SCGC6_TPM1; \
743 FTM1_SC = 0; \
744 FTM1_CNT = 0; \
745 FTM1_MOD = (F_PLL/2000) / val - 1; \
746 FTM1_C0V = (F_PLL/6000) / val - 1; \
747 FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0); \
748 })
749 #define TIMER_CONFIG_NORMAL() ({ \
750 SIM_SCGC6 |= SIM_SCGC6_TPM1; \
751 FTM1_SC = 0; \
752 FTM1_CNT = 0; \
753 FTM1_MOD = (F_PLL/40000) - 1; \
754 FTM1_C0V = 0; \
755 FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0) | FTM_SC_TOF | FTM_SC_TOIE; \
756 })
757 #define IR_SEND_PIN 16
758 
759 // defines for timer_tiny0 (8 bits)
760 #elif defined(IR_USE_TIMER_TINY0)
761 #define TIMER_RESET
762 #define TIMER_ENABLE_PWM (TCCR0A |= _BV(COM0B1))
763 #define TIMER_DISABLE_PWM (TCCR0A &= ~(_BV(COM0B1)))
764 #define TIMER_ENABLE_INTR (TIMSK |= _BV(OCIE0A))
765 #define TIMER_DISABLE_INTR (TIMSK &= ~(_BV(OCIE0A)))
766 #define TIMER_INTR_NAME TIMER0_COMPA_vect
767 #define TIMER_CONFIG_KHZ(val) ({ \
768  const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
769  TCCR0A = _BV(WGM00); \
770  TCCR0B = _BV(WGM02) | _BV(CS00); \
771  OCR0A = pwmval; \
772  OCR0B = pwmval * DUTY_CYCLE / 100; \
773 })
774 #define TIMER_COUNT_TOP (SYSCLOCK * USECPERTICK / 1000000)
775 #if (TIMER_COUNT_TOP < 256)
776 #define TIMER_CONFIG_NORMAL() ({ \
777  TCCR0A = _BV(WGM01); \
778  TCCR0B = _BV(CS00); \
779  OCR0A = TIMER_COUNT_TOP; \
780  TCNT0 = 0; \
781 })
782 #else
783 #define TIMER_CONFIG_NORMAL() ({ \
784  TCCR0A = _BV(WGM01); \
785  TCCR0B = _BV(CS01); \
786  OCR0A = TIMER_COUNT_TOP / 8; \
787  TCNT0 = 0; \
788 })
789 #endif
790 
791 #define IR_SEND_PIN 1 /* ATtiny85 */
792 
793 #elif defined(IR_USE_TIMER_4809_1)
794 // ATmega4809 TCB0
795 #define TIMER_RESET TCB0.INTFLAGS = TCB_CAPT_bm
796 #define TIMER_ENABLE_PWM (TCB0.CTRLB = TCB_CNTMODE_PWM8_gc)
797 #define TIMER_DISABLE_PWM (TCB0.CTRLB &= ~(TCB_CNTMODE_PWM8_gc))
798 #define TIMER_ENABLE_INTR (TCB0.INTCTRL = TCB_CAPT_bm)
799 #define TIMER_DISABLE_INTR (TCB0.INTCTRL &= ~(TCB_CAPT_bm))
800 #define TIMER_INTR_NAME TCB0_INT_vect
801 #define TIMER_CONFIG_KHZ(val) ({ \
802  const uint32_t pwmval = SYSCLOCK / 2000 / (val); \
803  TCB0.CTRLB = TCB_CNTMODE_PWM8_gc; \
804  TCB0.CCMPL = pwmval; \
805  TCB0.CCMPH = pwmval * DUTY_CYCLE / 100; \
806  TCB0.CTRLA = (TCB_CLKSEL_CLKDIV1_gc) | (TCB_ENABLE_bm); \
807 })
808 #define TIMER_COUNT_TOP ((SYSCLOCK * USECPERTICK / 1000000))
809 #define TIMER_CONFIG_NORMAL() ({ \
810  TCB0.CTRLB = (TCB_CNTMODE_INT_gc); \
811  TCB0.CCMP = TIMER_COUNT_TOP; \
812  TCB0.INTCTRL = TCB_CAPT_bm; \
813  TCB0.CTRLA = (TCB_CLKSEL_CLKDIV1_gc) | (TCB_ENABLE_bm); \
814 })
815 
816 #define IR_SEND_PIN 6 /* Nano Every, Uno WiFi Rev2 */
817 //---------------------------------------------------------
818 // ESP32 (ESP8266 should likely be added here too)
819 //
820 
821 // ESP32 has it own timer API and does not use these macros, but to avoid ifdef'ing
822 // them out in the common code, they are defined to no-op. This allows the code to compile
823 // (which it wouldn't otherwise) but irsend will not work until ESP32 specific code is written
824 // for that -- merlin
825 // As a warning, sending timing specific code from an ESP32 can be challenging if you need 100%
826 // reliability because the arduino code may be interrupted and cause your sent waveform to be the
827 // wrong length. This is specifically an issue for neopixels which require 800Khz resolution.
828 // IR may just work as is with the common code since it's lower frequency, but if not, the other
829 // way to do this on ESP32 is using the RMT built in driver like in this incomplete library below
830 // https://github.com/ExploreEmbedded/ESP32_RMT
831 #elif defined(IR_TIMER_USE_ESP32)
832 
833 #if ! defined(IR_SEND_PIN)
834 #define IR_SEND_PIN 4 // can use any pin, no timer restrictions
835 #endif
836 
837 #if ! defined(LEDCHANNEL)
838 #define LEDCHANNEL 0 // The channel used for PWM 0 to 7 are high speed PWM channels
839 #endif
840 
841 #define TIMER_RESET
842 #define TIMER_ENABLE_PWM ledcWrite(LEDCHANNEL, DUTY_CYCLE) // we must use channel here not pin number
843 #define TIMER_DISABLE_PWM ledcWrite(LEDCHANNEL, 0)
844 
845 #ifdef ISR
846 #undef ISR
847 #endif
848 #define ISR(f) void IRTimer()
849 
850 #elif defined(ARDUINO_ARCH_SAMD)
851 // use timer 3 hardcoded at this time
852 
853 #define IR_SEND_PIN 9
854 
855 #define TIMER_RESET
856 #define TIMER_ENABLE_PWM // Not presently used
857 #define TIMER_DISABLE_PWM
858 #define TIMER_ENABLE_INTR NVIC_EnableIRQ(TC3_IRQn) // Not presently used
859 #define TIMER_DISABLE_INTR NVIC_DisableIRQ(TC3_IRQn)
860 #define TIMER_INTR_NAME TC3_Handler // Not presently used
861 #define TIMER_CONFIG_KHZ(f)
862 
863 #ifdef ISR
864 #undef ISR
865 #endif
866 #define ISR(f) void irs()
867 
868 //---------------------------------------------------------
869 // Unknown Timer
870 //
871 #else
872 #error "Internal code configuration error, no known IR_USE_TIMER* defined\n"
873 #endif
874 
875 #endif // ! IRremoteBoardDefs_h