58 #if defined(SEND_PWM_BY_TIMER) && ( (defined(ESP32) || defined(ARDUINO_ARCH_RP2040) || defined(PARTICLE)) || defined(ARDUINO_ARCH_MBED) )
59 #define SEND_PWM_DOES_NOT_USE_RECEIVE_TIMER // Receive timer and send generation timer are independent here.
62 #if defined(IR_SEND_PIN) && defined(SEND_PWM_BY_TIMER) && !defined(SEND_PWM_DOES_NOT_USE_RECEIVE_TIMER) // For ESP32 etc. IR_SEND_PIN definition is useful
63 #undef IR_SEND_PIN // To avoid "warning: "IR_SEND_PIN" redefined". The user warning is done at IRremote.hpp line 202.
66 #if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
68 #define IR_SEND_DUTY_CYCLE_PERCENT_FOR_LEVEL_HIGH (100 - IR_SEND_DUTY_CYCLE_PERCENT)
70 #define IR_SEND_DUTY_CYCLE_PERCENT_FOR_LEVEL_HIGH IR_SEND_DUTY_CYCLE_PERCENT
100 #if defined (DOXYGEN)
150 #elif defined(__AVR__)
159 #if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328PB__) || defined(__AVR_ATmega168__) \
160 || defined(__AVR_ATmega88P__) || defined(__AVR_ATmega88PB__)
161 # if !defined(IR_USE_AVR_TIMER1) && !defined(IR_USE_AVR_TIMER2)
163 #define IR_USE_AVR_TIMER2 // send pin = pin 3
167 #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
168 # if !defined(IR_USE_AVR_TIMER1) && !defined(IR_USE_AVR_TIMER2) && !defined(IR_USE_AVR_TIMER3) && !defined(IR_USE_AVR_TIMER4) && !defined(IR_USE_AVR_TIMER5)
170 #define IR_USE_AVR_TIMER2 // send pin = pin 9
177 #elif defined(__AVR_ATmega32U4__) && ! defined(TEENSYDUINO) && ! defined(ARDUINO_AVR_PROMICRO)
178 # if !defined(IR_USE_AVR_TIMER1) && !defined(IR_USE_AVR_TIMER3) && !defined(IR_USE_AVR_TIMER4_HS)
180 #define IR_USE_AVR_TIMER3 // send pin = pin 5
185 #elif defined(__AVR_ATmega808__) || defined(__AVR_ATmega809__) || defined(__AVR_ATmega3208__) || defined(__AVR_ATmega3209__) \
186 || defined(__AVR_ATmega1608__) || defined(__AVR_ATmega1609__) || defined(__AVR_ATmega4808__) || defined(__AVR_ATmega4809__)
187 # if !defined(IR_USE_AVR_TIMER_B)
188 #define IR_USE_AVR_TIMER_B // send pin = pin 6 on ATmega4809 1 on ATmega4809
191 #elif defined(__AVR_ATtiny816__) || defined(__AVR_ATtiny1604__) || defined(__AVR_ATtiny1614__) || defined(__AVR_ATtiny1624__) \
192 || defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__) // e.g. TinyCore boards
193 # if !defined(IR_USE_AVR_TIMER_A) && !defined(IR_USE_AVR_TIMER_D)
194 #define IR_USE_AVR_TIMER_A // use this if you use megaTinyCore, Tone is on TCB and millis() on TCD
199 #elif defined(__AVR_ATmega8U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega8__)
200 # if !defined(IR_USE_AVR_TIMER1)
201 #define IR_USE_AVR_TIMER1 // send pin = pin C6
205 #elif defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny88__)
206 # if !defined(IR_USE_AVR_TIMER1)
207 #define IR_USE_AVR_TIMER1 // send pin = pin 6, no tone() available when using ATTinyCore
210 #elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)
211 # if !defined(IR_USE_AVR_TIMER1)
212 #define IR_USE_AVR_TIMER1 // send pin = pin PB1 / 8
214 #define USE_TIMER_CHANNEL_B
217 #elif defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
218 # if !defined(IR_USE_AVR_TIMER_TINY0) && !defined(IR_USE_AVR_TIMER_TINY1)
219 # if defined(ARDUINO_AVR_DIGISPARK) // tested with 16 and 8 MHz
220 #define IR_USE_AVR_TIMER_TINY0 // send pin = pin 1
224 #define IR_USE_AVR_TIMER_TINY1 // send pin = pin 4
231 #elif defined(ARDUINO_AVR_PROMICRO)
232 # if !defined(IR_USE_AVR_TIMER1) && !defined(IR_USE_AVR_TIMER3) && !defined(IR_USE_AVR_TIMER4_HS)
234 #define IR_USE_AVR_TIMER3 // send pin = pin 5
242 #elif defined(__AVR_AT90USB162__)
243 # if !defined(IR_USE_AVR_TIMER1)
244 #define IR_USE_AVR_TIMER1 // send pin = pin 17
248 #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
249 # if !defined(IR_USE_AVR_TIMER1) && !defined(IR_USE_AVR_TIMER2) && !defined(IR_USE_AVR_TIMER3)
251 #define IR_USE_AVR_TIMER2 // send pin = pin 1
256 #elif defined(__AVR_ATmega32U4__) && defined(TEENSYDUINO)
257 # if !defined(IR_USE_AVR_TIMER1) && !defined(IR_USE_AVR_TIMER3) && !defined(IR_USE_AVR_TIMER4_HS)
260 #define IR_USE_AVR_TIMER4_HS // send pin = pin 10 (Teensy 2.0 - physical pin: C7)
267 #elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2560__)
268 # if !defined(IR_USE_AVR_TIMER1)
269 #define IR_USE_AVR_TIMER1 // send pin = pin 13
275 #elif defined(__AVR_ATmega8515__) || defined(__AVR_ATmega162__)
276 # if !defined(IR_USE_AVR_TIMER1) && !defined(IR_USE_AVR_TIMER3)
277 #define IR_USE_AVR_TIMER1 // send pin = pin 13
285 #elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)
286 # if !defined(IR_USE_AVR_TIMER1) && !defined(IR_USE_AVR_TIMER2) && !defined(IR_USE_AVR_TIMER3)
288 #define IR_USE_AVR_TIMER2 // send pin = pin 14
293 #elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \
294 || defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \
295 || defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \
296 || defined(__AVR_ATmega164P__)
297 # if !defined(IR_USE_AVR_TIMER1) && !defined(IR_USE_AVR_TIMER2)
299 #define IR_USE_AVR_TIMER2 // send pin = pin 14
303 #elif defined(__AVR_ATmega8535__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__)
304 # if !defined(IR_USE_AVR_TIMER1)
305 #define IR_USE_AVR_TIMER1 // send pin = pin 13
315 #if defined(IR_USE_AVR_TIMER1)
318 #define TIMSK TIMSK1 // use the value of TIMSK1 for the statements below
322 TIMSK |= _BV(OCIE1A);
325 TIMSK &= ~_BV(OCIE1A);
328 # if defined(USE_TIMER_CHANNEL_B)
329 # if defined(TIMER1_COMPB_vect)
330 #define TIMER_INTR_NAME TIMER1_COMPB_vect
331 # elif defined(TIM1_COMPB_vect)
332 #define TIMER_INTR_NAME TIM1_COMPB_vect
335 # if defined(TIMER1_COMPA_vect)
336 #define TIMER_INTR_NAME TIMER1_COMPA_vect
337 # elif defined(TIM1_COMPA_vect)
338 #define TIMER_INTR_NAME TIM1_COMPA_vect
344 TCCR1B = _BV(WGM12) | _BV(CS10);
349 # if defined(SEND_PWM_BY_TIMER)
351 # if defined(CORE_OC1A_PIN)
352 #define IR_SEND_PIN CORE_OC1A_PIN // Teensy
354 # elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
355 #define IR_SEND_PIN 11 // Arduino Mega
358 # elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \
359 || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \
360 || defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \
361 || defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \
362 || defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \
363 || defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__) \
364 || defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) \
365 || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) \
366 || defined(__AVR_ATmega8515__) || defined(__AVR_ATmega162__)
367 #define IR_SEND_PIN 13
369 # elif defined(__AVR_ATtiny84__)
370 #define IR_SEND_PIN 6
372 # elif defined(__AVR_ATtiny88__)
373 #define IR_SEND_PIN 8
375 # elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)
379 # if defined(USE_TIMER_CHANNEL_B)
380 #define IR_SEND_PIN PIN_PB1 // OC1BU / PB1 / Pin9 at ATTinyCore
385 #define IR_SEND_PIN PIN_PB0 // OC1AU / PB1 / Pin8 at ATTinyCore
391 # else // defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)
392 #define IR_SEND_PIN 9 // OC1A Arduino Duemilanove, Diecimila, LilyPad, Sparkfun Pro Micro, Leonardo, MH-ET Tiny88 etc.
393 # endif // Set IR_SEND_PIN depending on CPU
395 # if defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)
397 # if defined(USE_TIMER_CHANNEL_B)
400 TCCR1A |= _BV(COM1B1);
401 TCCR1D |= _BV(OC1BU);
409 TCCR1A |= _BV(COM1A1);
410 TCCR1D |= _BV(OC1AU);
415 # endif // defined(USE_TIMER_CHANNEL_B)
419 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
420 # if defined(IR_SEND_PIN)
423 if (__builtin_constant_p(sendPin)) {
426 digitalWrite(sendPin, HIGH);
428 # endif // defined(IR_SEND_PIN)
429 # endif // defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
431 # else // defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)
432 # if defined(USE_TIMER_CHANNEL_B)
435 TCCR1A |= _BV(COM1B1);
438 TCCR1A &= ~(_BV(COM1B1));
439 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
440 # if defined(IR_SEND_PIN)
443 if (__builtin_constant_p(sendPin)) {
446 digitalWrite(sendPin, HIGH);
448 # endif // defined(IR_SEND_PIN)
449 # endif // defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
451 # else // defined(USE_TIMER_CHANNEL_B)
454 TCCR1A |= _BV(COM1A1);
457 TCCR1A &= ~(_BV(COM1A1));
458 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
459 # if defined(IR_SEND_PIN)
462 if (__builtin_constant_p(sendPin)) {
465 digitalWrite(sendPin, HIGH);
467 # endif // defined(IR_SEND_PIN)
468 # endif // defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
470 # endif // defined(USE_TIMER_CHANNEL_B)
472 # endif // defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)
481 # if (((F_CPU / 2000) / 38) < 256)
482 const uint16_t tPWMWrapValue = (F_CPU / 2000) / (aFrequencyKHz);
484 TCCR1B = _BV(WGM13) | _BV(CS10);
485 ICR1 = tPWMWrapValue - 1;
486 # if defined(USE_TIMER_CHANNEL_B)
493 const uint16_t tPWMWrapValue = ((F_CPU / 8) / 2000) / (aFrequencyKHz);
495 TCCR1B = _BV(WGM13) | _BV(CS11);
496 ICR1 = tPWMWrapValue - 1;
497 # if defined(USE_TIMER_CHANNEL_B)
503 # endif // if (((F_CPU / 2000) / 38) < 256)
505 # endif // defined(SEND_PWM_BY_TIMER) - Timer1
510 #elif defined(IR_USE_AVR_TIMER2)
513 TIMSK2 = _BV(OCIE2B);
518 #define TIMER_INTR_NAME TIMER2_COMPB_vect // We use TIMER2_COMPB_vect to be compatible with tone() library
519 #define TIMER_COUNT_TOP (F_CPU * MICROS_PER_TICK / MICROS_IN_ONE_SECOND)
522 # if (TIMER_COUNT_TOP < 256)
525 OCR2A = TIMER_COUNT_TOP;
526 OCR2B = TIMER_COUNT_TOP;
531 OCR2A = TIMER_COUNT_TOP / 8;
532 OCR2B = TIMER_COUNT_TOP / 8;
537 # if defined(SEND_PWM_BY_TIMER)
539 # if defined(CORE_OC2B_PIN)
540 #define IR_SEND_PIN CORE_OC2B_PIN // Teensy
542 # elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
543 #define IR_SEND_PIN 9 // Arduino Mega
545 # elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \
546 || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \
547 || defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \
548 || defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \
549 || defined(__AVR_ATmega164P__)
550 #define IR_SEND_PIN 14 // MightyCore, MegaCore
558 #define IR_SEND_PIN 3 // Arduino Uno Pin PD3, Duemilanove, Diecimila, LilyPad, etc
559 # endif // Set IR_SEND_PIN depending on CPU
563 TCCR2A |= _BV(COM2B1);
566 TCCR2A &= ~(_BV(COM2B1));
567 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
568 # if defined(IR_SEND_PIN)
571 if (__builtin_constant_p(sendPin)) {
574 digitalWrite(sendPin, HIGH);
576 # endif // defined(IR_SEND_PIN)
577 # endif // defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
587 # if (((F_CPU / 2000) / 38) < 256)
593 const uint16_t tPWMWrapValue = (F_CPU / 2000) / (aFrequencyKHz);
595 TCCR2B = _BV(WGM22) | _BV(CS20);
596 OCR2A = tPWMWrapValue - 1;
600 const uint16_t tPWMWrapValue = ((F_CPU / 8) / 2000) / (aFrequencyKHz);
602 TCCR2B = _BV(WGM22) | _BV(CS21);
603 OCR2A = tPWMWrapValue - 1;
608 # endif // defined(SEND_PWM_BY_TIMER)
613 #elif defined(IR_USE_AVR_TIMER3)
616 TIMSK3 = _BV(OCIE3B);
621 #define TIMER_INTR_NAME TIMER3_COMPB_vect
625 TCCR3B = _BV(WGM32) | _BV(CS30);
631 # if defined(SEND_PWM_BY_TIMER)
633 # if defined(CORE_OC3A_PIN)
634 #define IR_SEND_PIN CORE_OC3A_PIN // Teensy
636 # elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) \
637 || defined(__AVR_ATmega32U4__) || defined(ARDUINO_AVR_PROMICRO)
638 #define IR_SEND_PIN 5 // Arduino Mega, Arduino Leonardo, Sparkfun Pro Micro
640 # elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)
641 #define IR_SEND_PIN 6 // MightyCore, MegaCore
644 #error Please add OC3A pin number here
645 # endif // Set IR_SEND_PIN depending on CPU
649 TCCR3A |= _BV(COM3A1);
652 TCCR3A &= ~(_BV(COM3A1));
653 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
654 # if defined(IR_SEND_PIN)
657 if (__builtin_constant_p(sendPin)) {
660 digitalWrite(sendPin, HIGH);
662 # endif // defined(IR_SEND_PIN)
663 # endif // defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
671 # if F_CPU > 16000000
672 #error "Creating timer PWM with timer 3 is not supported for F_CPU > 16 MHz"
676 const uint16_t tPWMWrapValue = (F_CPU / 2000) / (aFrequencyKHz);
678 TCCR3B = _BV(WGM33) | _BV(CS30);
679 ICR3 = tPWMWrapValue - 1;
683 # endif // defined(SEND_PWM_BY_TIMER)
688 #elif defined(IR_USE_AVR_TIMER4)
690 TIMSK4 = _BV(OCIE4A);
695 #define TIMER_INTR_NAME TIMER4_COMPA_vect
699 TCCR4B = _BV(WGM42) | _BV(CS40);
704 # if defined(SEND_PWM_BY_TIMER)
706 # if defined(CORE_OC4A_PIN)
707 #define IR_SEND_PIN CORE_OC4A_PIN
708 # elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
709 #define IR_SEND_PIN 6 // Arduino Mega
711 #error Please add OC4A pin number here
716 TCCR4A |= _BV(COM4A1);
719 TCCR4A &= ~(_BV(COM4A1));
720 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
721 # if defined(IR_SEND_PIN)
724 if (__builtin_constant_p(sendPin)) {
727 digitalWrite(sendPin, HIGH);
729 # endif // defined(IR_SEND_PIN)
730 # endif // defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
734 # if F_CPU > 16000000
735 #error "Creating timer PWM with timer 4 is not supported for F_CPU > 16 MHz"
738 const uint16_t tPWMWrapValue = (F_CPU / 2000) / (aFrequencyKHz);
740 TCCR4B = _BV(WGM43) | _BV(CS40);
741 ICR4 = tPWMWrapValue - 1;
745 # endif // defined(SEND_PWM_BY_TIMER)
750 #elif defined(IR_USE_AVR_TIMER4_HS)
758 #define TIMER_INTR_NAME TIMER4_OVF_vect
772 # if defined(SEND_PWM_BY_TIMER)
773 # if defined(CORE_OC4A_PIN)
774 #define IR_SEND_PIN CORE_OC4A_PIN // Teensy 2.0
775 # elif defined(ARDUINO_AVR_PROMICRO)
776 #define IR_SEND_PIN 5 // Sparkfun Pro Micro
777 # elif defined(__AVR_ATmega32U4__)
778 #define IR_SEND_PIN 13 // Leonardo
780 #error Please add OC4A pin number here
783 # if defined(ARDUINO_AVR_PROMICRO) // Sparkfun Pro Micro
786 TCCR4A |= _BV(COM4A0);
789 TCCR4A &= ~(_BV(COM4A0));
790 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
791 # if defined(IR_SEND_PIN)
794 if (__builtin_constant_p(sendPin)) {
797 digitalWrite(sendPin, HIGH);
799 # endif // defined(IR_SEND_PIN)
800 # endif // defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
806 TCCR4A |= _BV(COM4A1);
810 TCCR4A &= ~(_BV(COM4A1));
811 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
812 # if defined(IR_SEND_PIN)
815 if (__builtin_constant_p(sendPin)) {
818 digitalWrite(sendPin, HIGH);
820 # endif // defined(IR_SEND_PIN)
821 # endif // defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
831 #error "Creating timer PWM with timer 4 HS is not supported for F_CPU > 16 MHz"
835 const uint16_t tPWMWrapValue = ((F_CPU / 2000) / (aFrequencyKHz)) - 1;
836 TCCR4A = (1 << PWM4A);
839 TCCR4D = (1 << WGM40);
841 TC4H = tPWMWrapValue >> 8;
842 OCR4C = tPWMWrapValue;
847 # endif // defined(SEND_PWM_BY_TIMER)
852 #elif defined(IR_USE_AVR_TIMER5)
855 TIMSK5 = _BV(OCIE5A);
860 #define TIMER_INTR_NAME TIMER5_COMPA_vect
864 TCCR5B = _BV(WGM52) | _BV(CS50);
869 # if defined(SEND_PWM_BY_TIMER)
870 # if defined(CORE_OC5A_PIN)
871 #define IR_SEND_PIN CORE_OC5A_PIN
872 # elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
873 #define IR_SEND_PIN 46 // Arduino Mega
875 #error Please add OC5A pin number here
880 TCCR5A |= _BV(COM5A1);
883 TCCR5A &= ~(_BV(COM5A1));
884 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
885 # if defined(IR_SEND_PIN)
888 if (__builtin_constant_p(sendPin)) {
891 digitalWrite(sendPin, HIGH);
893 # endif // defined(IR_SEND_PIN)
894 # endif // defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
903 #error "Creating timer PWM with timer 5 is not supported for F_CPU > 16 MHz"
907 const uint16_t tPWMWrapValue = (F_CPU / 2000) / (aFrequencyKHz);
909 TCCR5B = _BV(WGM53) | _BV(CS50);
910 ICR5 = tPWMWrapValue - 1;
914 # endif // defined(SEND_PWM_BY_TIMER)
919 #elif defined(IR_USE_AVR_TIMER_TINY0)
922 TIMSK |= _BV(OCIE0A);
925 TIMSK &= ~(_BV(OCIE0A));
927 #define TIMER_INTR_NAME TIMER0_COMPA_vect
929 #define TIMER_COUNT_TOP (F_CPU * MICROS_PER_TICK / MICROS_IN_ONE_SECOND)
932 # if (TIMER_COUNT_TOP < 256)
935 OCR0A = TIMER_COUNT_TOP;
940 OCR0A = TIMER_COUNT_TOP / 8;
945 # if defined(SEND_PWM_BY_TIMER)
946 #define IR_SEND_PIN 1
950 TCCR0A |= _BV(COM0B1);
953 TCCR0A &= ~(_BV(COM0B1));
954 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
955 # if defined(IR_SEND_PIN)
958 if (__builtin_constant_p(sendPin)) {
961 digitalWrite(sendPin, HIGH);
963 # endif // defined(IR_SEND_PIN)
964 # endif // defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
972 # if F_CPU > 16000000
973 #error "Creating timer PWM with timer TINY0 is not supported for F_CPU > 16 MHz"
977 const uint16_t tPWMWrapValue = (F_CPU / 2000) / (aFrequencyKHz);
979 TCCR0B = _BV(WGM02) | _BV(CS00);
980 OCR0A = tPWMWrapValue - 1;
984 # endif // defined(SEND_PWM_BY_TIMER)
989 #elif defined(IR_USE_AVR_TIMER_TINY1)
992 TIMSK |= _BV(OCIE1B);
995 TIMSK &= ~(_BV(OCIE1B));
997 #define TIMER_INTR_NAME TIMER1_COMPB_vect
999 #define TIMER_COUNT_TOP (F_CPU * MICROS_PER_TICK / MICROS_IN_ONE_SECOND)
1002 # if (TIMER_COUNT_TOP < 256)
1003 TCCR1 = _BV(CTC1) | _BV(CS10);
1005 OCR1C = TIMER_COUNT_TOP;
1008 TCCR1 = _BV(CTC1) | _BV(CS12);
1010 OCR1C = TIMER_COUNT_TOP / 8;
1015 # if defined(SEND_PWM_BY_TIMER)
1016 #define IR_SEND_PIN 4
1020 GTCCR |= _BV(PWM1B) | _BV(COM1B0);
1023 GTCCR &= ~(_BV(PWM1B) | _BV(COM1B0));
1024 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
1025 # if defined(IR_SEND_PIN)
1028 if (__builtin_constant_p(sendPin)) {
1031 digitalWrite(sendPin, HIGH);
1033 # endif // defined(IR_SEND_PIN)
1034 # endif // defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
1044 # if (((F_CPU / 1000) / 38) < 256)
1045 const uint16_t tPWMWrapValue = (F_CPU / 1000) / (aFrequencyKHz);
1046 TCCR1 = _BV(CTC1) | _BV(CS10);
1047 OCR1C = tPWMWrapValue - 1;
1050 GTCCR = _BV(PWM1B) | _BV(COM1B0);
1052 const uint16_t tPWMWrapValue = ((F_CPU / 2) / 1000) / (aFrequencyKHz);
1053 TCCR1 = _BV(CTC1) | _BV(CS11);
1054 OCR1C = tPWMWrapValue - 1;
1057 GTCCR = _BV(PWM1B) | _BV(COM1B0);
1060 # endif // defined(SEND_PWM_BY_TIMER)
1065 #elif defined(IR_USE_AVR_TIMER_A)
1066 #define TIMER_REQUIRES_RESET_INTR_PENDING
1068 TCA0.SINGLE.INTFLAGS = TCA_SINGLE_OVF_bm;
1071 TCA0.SINGLE.INTCTRL = TCA_SINGLE_OVF_bm;
1074 TCA0.SINGLE.INTCTRL &= ~(TCA_SINGLE_OVF_bm);
1076 #define TIMER_INTR_NAME TCA0_OVF_vect
1083 TCA0.SINGLE.CTRLD = 0;
1084 TCA0.SINGLE.CTRLB = TCA_SINGLE_WGMODE_NORMAL_gc;
1086 TCA0.SINGLE.CTRLA = TCA_SINGLE_CLKSEL_DIV1_gc | TCA_SINGLE_ENABLE_bm;
1089 # if defined(SEND_PWM_BY_TIMER)
1090 #error "No support for hardware PWM generation for ATtiny3216/17 etc."
1091 # endif // defined(SEND_PWM_BY_TIMER)
1096 #elif defined(IR_USE_AVR_TIMER_B)
1099 #define TIMER_REQUIRES_RESET_INTR_PENDING
1101 TCB0.INTFLAGS = TCB_CAPT_bm;
1104 TCB0.INTCTRL = TCB_CAPT_bm;
1107 TCB0.INTCTRL &= ~(TCB_CAPT_bm);
1109 #define TIMER_INTR_NAME TCB0_INT_vect
1112 TCB0.CTRLB = (TCB_CNTMODE_INT_gc);
1114 TCB0.INTFLAGS = TCB_CAPT_bm;
1115 TCB0.CTRLA = (TCB_CLKSEL_CLKDIV1_gc) | (TCB_ENABLE_bm);
1118 # if defined(SEND_PWM_BY_TIMER)
1119 # if defined(__AVR_ATmega4808__) || defined(__AVR_ATmega4809__)
1120 #define IR_SEND_PIN 6 // PF4 on ATmega4809 / Nano Every (see pins_arduino.h digital_pin_to_timer)
1122 #error SEND_PWM_BY_TIMER not yet supported for this CPU
1127 TCB0.CTRLB |= TCB_CCMPEN_bm;
1130 TCB0.CTRLB &= ~(TCB_CCMPEN_bm);
1131 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
1132 # if defined(IR_SEND_PIN)
1135 if (__builtin_constant_p(sendPin)) {
1138 digitalWrite(sendPin, HIGH);
1140 # endif // defined(IR_SEND_PIN)
1141 # endif // defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
1149 #if F_CPU > 16000000
1151 #error "Creating timer PWM with timer TCB0 is not possible for F_CPU > 16 MHz"
1155 const uint16_t tPWMWrapValue = (F_CPU / 2000) / (aFrequencyKHz);
1156 TCB0.CTRLB = TCB_CNTMODE_PWM8_gc;
1157 TCB0.CCMPL = tPWMWrapValue - 1;
1159 TCB0.CTRLA = (TCB_CLKSEL_CLKDIV2_gc) | (TCB_ENABLE_bm);
1162 # endif // defined(SEND_PWM_BY_TIMER)
1167 #elif defined(IR_USE_AVR_TIMER_D)
1169 #define TIMER_REQUIRES_RESET_INTR_PENDING
1171 TCD0.INTFLAGS = TCD_OVF_bm;
1174 TCD0.INTCTRL = TCD_OVF_bm;
1179 #define TIMER_INTR_NAME TCD0_OVF_vect
1183 TCD0.CTRLB = TCD_WGMODE_ONERAMP_gc;
1187 _PROTECTED_WRITE(TCD0.FAULTCTRL, 0);
1189 TCD0.INTFLAGS = TCD_OVF_bm;
1193 TCD0.CTRLA = TCD_ENABLE_bm | TCD_CLKSEL_SYSCLK_gc | TCD_CNTPRES_DIV1_gc;
1196 # if defined(SEND_PWM_BY_TIMER)
1197 #define IR_SEND_PIN 13
1199 void timerEnableSendPWM() {
1201 _PROTECTED_WRITE(TCD0.FAULTCTRL, FUSE_CMPAEN_bm);
1203 TCD0.CTRLA = TCD_ENABLE_bm | TCD_CLKSEL_SYSCLK_gc | TCD_CNTPRES_DIV1_gc;
1207 timerEnableSendPWM();
1211 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
1212 # if defined(IR_SEND_PIN)
1215 if (__builtin_constant_p(sendPin)) {
1218 digitalWrite(sendPin, HIGH);
1220 # endif // defined(IR_SEND_PIN)
1221 # endif // defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
1231 const uint16_t tPWMWrapValue = (F_CPU / 1000) / (aFrequencyKHz);
1235 TCD0.CTRLB = TCD_WGMODE_ONERAMP_gc;
1238 TCD0.CMPBCLR = tPWMWrapValue - 1;
1244 TCD0.INTFLAGS = TCD_OVF_bm;
1245 TCD0.INTCTRL = TCD_OVF_bm;
1248 # endif // defined(SEND_PWM_BY_TIMER)
1251 #error Internal code configuration error, no timer functions implemented for this AVR CPU / board
1252 #endif //defined(IR_USE_AVR_TIMER*)
1260 #elif defined(ARDUINO_ARCH_RENESAS)
1261 #include "FspTimer.h"
1262 FspTimer s50usTimer;
1270 void IRTimerInterruptHandlerHelper(timer_callback_args_t __attribute((unused)) *p_args) {
1283 uint8_t tTimerType = GPT_TIMER;
1284 int8_t tIndex = FspTimer::get_available_timer(tTimerType);
1285 if (tIndex < 0 || tTimerType != GPT_TIMER) {
1287 tIndex = FspTimer::get_available_timer(tTimerType,
true);
1294 IRTimerInterruptHandlerHelper);
1295 s50usTimer.setup_overflow_irq();
1300 # if defined(SEND_PWM_BY_TIMER)
1301 #error PWM generation by hardware not yet implemented for Arduino Uno R4
1312 # if defined(IR_SEND_PIN)
1321 #elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
1324 #define TIMER_REQUIRES_RESET_INTR_PENDING
1326 uint8_t tmp __attribute__((unused)) = CMT_MSC;
1330 NVIC_ENABLE_IRQ(IRQ_CMT);
1331 NVIC_SET_PRIORITY(IRQ_CMT, 48);
1334 NVIC_DISABLE_IRQ(IRQ_CMT);
1337 #define TIMER_INTR_NAME cmt_isr
1341 #define ISR(f) void f(void)
1343 #define CMT_PPS_DIV ((F_BUS + 7999999) / 8000000)
1344 # if F_BUS < 8000000
1345 #error IRremote requires at least 8 MHz on Teensy 3.x
1349 SIM_SCGC4 |= SIM_SCGC4_CMT;
1350 CMT_PPS = CMT_PPS_DIV - 1;
1356 CMT_CMD4 = (F_BUS / 160000 + CMT_PPS_DIV / 2) / CMT_PPS_DIV - 31;
1361 # if defined(SEND_PWM_BY_TIMER)
1362 #define IR_SEND_PIN 5
1366 CORE_PIN5_CONFIG = PORT_PCR_MUX(2) | PORT_PCR_DSE | PORT_PCR_SRE;
1371 CORE_PIN5_CONFIG = PORT_PCR_MUX(1) | PORT_PCR_DSE | PORT_PCR_SRE;
1381 # if defined(IR_SEND_PIN)
1387 SIM_SCGC4 |= SIM_SCGC4_CMT;
1388 SIM_SOPT2 |= SIM_SOPT2_PTD7PAD;
1389 CMT_PPS = CMT_PPS_DIV - 1;
1390 CMT_CGH1 = ((F_BUS / CMT_PPS_DIV / 3000) + ((aFrequencyKHz) / 2)) / (aFrequencyKHz);
1391 CMT_CGL1 = ((F_BUS / CMT_PPS_DIV / 1500) + ((aFrequencyKHz) / 2)) / (aFrequencyKHz);
1399 # endif // defined(SEND_PWM_BY_TIMER)
1404 #elif defined(__MKL26Z64__)
1407 #define TIMER_REQUIRES_RESET_INTR_PENDING
1409 FTM1_SC |= FTM_SC_TOF;
1412 NVIC_ENABLE_IRQ(IRQ_FTM1);
1413 NVIC_SET_PRIORITY(IRQ_FTM1, 0);
1416 NVIC_DISABLE_IRQ(IRQ_FTM1);
1418 #define TIMER_INTR_NAME ftm1_isr
1422 #define ISR(f) void f(void)
1425 SIM_SCGC6 |= SIM_SCGC6_TPM1;
1428 FTM1_MOD = (F_PLL / 40000) - 1;
1430 FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0) | FTM_SC_TOF | FTM_SC_TOIE;
1433 # if defined(SEND_PWM_BY_TIMER)
1434 #define IR_SEND_PIN 16
1438 CORE_PIN16_CONFIG = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
1441 CORE_PIN16_CONFIG = PORT_PCR_MUX(1) | PORT_PCR_SRE;
1450 # if defined(IR_SEND_PIN)
1456 SIM_SCGC6 |= SIM_SCGC6_TPM1;
1459 FTM1_MOD = ((F_PLL / 2000) / aFrequencyKHz) - 1;
1460 FTM1_C0V = ((F_PLL / 6000) / aFrequencyKHz) - 1;
1461 FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0);
1463 # endif // defined(SEND_PWM_BY_TIMER)
1468 #elif defined(__IMXRT1062__)
1473 #define TIMER_REQUIRES_RESET_INTR_PENDING
1475 FLEXPWM1_SM3STS = FLEXPWM_SMSTS_RF;
1478 attachInterruptVector(IRQ_FLEXPWM1_3, pwm1_3_isr);
1479 FLEXPWM1_SM3STS = FLEXPWM_SMSTS_RF;
1480 FLEXPWM1_SM3INTEN = FLEXPWM_SMINTEN_RIE;
1481 NVIC_ENABLE_IRQ (IRQ_FLEXPWM1_3), NVIC_SET_PRIORITY(IRQ_FLEXPWM1_3, 48);
1484 NVIC_DISABLE_IRQ (IRQ_FLEXPWM1_3);
1486 #define TIMER_INTR_NAME pwm1_3_isr
1490 #define ISR(f) void (f)(void)
1493 uint32_t period = (float) F_BUS_ACTUAL * (
float) (
MICROS_PER_TICK) * 0.0000005f;
1494 uint32_t prescale = 0;
1495 while (period > 32767) {
1496 period = period >> 1;
1500 FLEXPWM1_FCTRL0 |= FLEXPWM_FCTRL0_FLVL(8);
1501 FLEXPWM1_FSTS0 = 0x0008;
1502 FLEXPWM1_MCTRL |= FLEXPWM_MCTRL_CLDOK(8);
1503 FLEXPWM1_SM3CTRL2 = FLEXPWM_SMCTRL2_INDEP;
1504 FLEXPWM1_SM3CTRL = FLEXPWM_SMCTRL_HALF | FLEXPWM_SMCTRL_PRSC(prescale);
1505 FLEXPWM1_SM3INIT = -period;
1506 FLEXPWM1_SM3VAL0 = 0;
1507 FLEXPWM1_SM3VAL1 = period;
1508 FLEXPWM1_SM3VAL2 = 0;
1509 FLEXPWM1_SM3VAL3 = 0;
1510 FLEXPWM1_SM3VAL4 = 0;
1511 FLEXPWM1_SM3VAL5 = 0;
1512 FLEXPWM1_MCTRL |= FLEXPWM_MCTRL_LDOK(8) | FLEXPWM_MCTRL_RUN(8);
1515 # if defined(SEND_PWM_BY_TIMER)
1516 #define IR_SEND_PIN 7
1518 FLEXPWM1_OUTEN |= FLEXPWM_OUTEN_PWMA_EN(8);
1519 IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_00 = 6;
1523 IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_00 = 5;
1524 FLEXPWM1_OUTEN &= ~FLEXPWM_OUTEN_PWMA_EN(8);
1533 # if defined(IR_SEND_PIN)
1539 uint32_t period = (float) F_BUS_ACTUAL / (
float) ((aFrequencyKHz) * 2000);
1540 uint32_t prescale = 0;
1541 while (period > 32767) {
1542 period = period >> 1;
1546 FLEXPWM1_FCTRL0 |= FLEXPWM_FCTRL0_FLVL(8);
1547 FLEXPWM1_FSTS0 = 0x0008;
1548 FLEXPWM1_MCTRL |= FLEXPWM_MCTRL_CLDOK(8);
1549 FLEXPWM1_SM3CTRL2 = FLEXPWM_SMCTRL2_INDEP;
1550 FLEXPWM1_SM3CTRL = FLEXPWM_SMCTRL_HALF | FLEXPWM_SMCTRL_PRSC(prescale);
1551 FLEXPWM1_SM3INIT = -period;
1552 FLEXPWM1_SM3VAL0 = 0;
1553 FLEXPWM1_SM3VAL1 = period;
1554 FLEXPWM1_SM3VAL2 = -(period / 3);
1555 FLEXPWM1_SM3VAL3 = period / 3;
1556 FLEXPWM1_SM3VAL4 = 0;
1557 FLEXPWM1_SM3VAL5 = 0;
1558 FLEXPWM1_MCTRL |= FLEXPWM_MCTRL_LDOK(8) | FLEXPWM_MCTRL_RUN(8);
1560 # endif // defined(SEND_PWM_BY_TIMER)
1565 #elif defined(ESP8266)
1566 # if defined(SEND_PWM_BY_TIMER)
1567 #error "No support for hardware PWM generation for ESP8266"
1568 # endif // defined(SEND_PWM_BY_TIMER)
1579 timer1_detachInterrupt();
1589 timer1_enable(TIM_DIV16, TIM_EDGE, TIM_LOOP);
1598 #elif defined(ESP32)
1599 # if !defined(ESP_ARDUINO_VERSION)
1600 #define ESP_ARDUINO_VERSION 0x010101 // Version 1.1.1
1605 hw_timer_t *s50usTimer =
nullptr;
1606 #define _IRREMOTE_ESP32_LEDC_RESOLUTION 8
1607 #define _IRREMOTE_ESP32_LEDC_RESOLUTION_MAX_PWM_VALUE 255
1610 # if ESP_ARDUINO_VERSION < (3 << 16 | 0 << 8 | 0) && !defined(SEND_LEDC_CHANNEL) // works also in case ESP_ARDUINO_VERSION_VAL is not defined
1611 #define SEND_LEDC_CHANNEL 0 // The channel used for PWM 0 to 7 are high speed PWM channels
1616 # if ESP_ARDUINO_VERSION >= (3 << 16 | 0 << 8 | 0)
1617 timerStart(s50usTimer);
1619 timerAlarmEnable(s50usTimer);
1624 # if ESP_ARDUINO_VERSION < (2 << 16 | 0 << 8 | 2)
1629 if (s50usTimer !=
nullptr) {
1630 timerDetachInterrupt(s50usTimer);
1631 timerEnd(s50usTimer);
1637 if (s50usTimer !=
nullptr) {
1639 # if ESP_ARDUINO_VERSION >= (3 << 16 | 0 << 8 | 0)
1640 timerStop(s50usTimer);
1642 timerAlarmDisable(s50usTimer);
1653 # if !defined(DISABLE_CODE_FOR_RECEIVER) // Otherwise the &IRReceiveTimerInterruptHandler is referenced, but not available
1658 if (s50usTimer ==
nullptr) {
1660 # if ESP_ARDUINO_VERSION >= (3 << 16 | 0 << 8 | 0)
1661 s50usTimer = timerBegin(1000000);
1662 timerStop(s50usTimer);
1666 s50usTimer = timerBegin(1, 80,
true);
1675 uint8_t sLastSendPin = 0;
1676 uint16_t sLastFrequencyKHz = 0;
1678 # if defined(SEND_PWM_BY_TIMER)
1681 # if ESP_ARDUINO_VERSION >= (3 << 16 | 0 << 8 | 0)
1682 # if defined(IR_SEND_PIN)
1694 # if ESP_ARDUINO_VERSION >= (3 << 16 | 0 << 8 | 0)
1695 # if defined(IR_SEND_PIN)
1696 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
1697 ledcWrite(
IR_SEND_PIN, _IRREMOTE_ESP32_LEDC_RESOLUTION_MAX_PWM_VALUE);
1702 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
1703 ledcWrite(
IrSender.
sendPin, _IRREMOTE_ESP32_LEDC_RESOLUTION_MAX_PWM_VALUE);
1710 ledcWrite(SEND_LEDC_CHANNEL, 0);
1720 # if ESP_ARDUINO_VERSION >= (3 << 16 | 0 << 8 | 0)
1721 # if defined(IR_SEND_PIN)
1722 if(sLastSendPin == 0){
1724 ledcAttach(
IR_SEND_PIN, aFrequencyKHz * 1000, _IRREMOTE_ESP32_LEDC_RESOLUTION);
1726 }
else if(sLastFrequencyKHz != aFrequencyKHz){
1729 ledcAttach(
IR_SEND_PIN, aFrequencyKHz * 1000, _IRREMOTE_ESP32_LEDC_RESOLUTION);
1730 sLastFrequencyKHz = aFrequencyKHz;
1733 if(sLastSendPin !=
IrSender.
sendPin || sLastFrequencyKHz != aFrequencyKHz){
1734 if(sLastSendPin != 0) {
1736 ledcDetach(sLastSendPin);
1738 ledcAttach(
IrSender.
sendPin, aFrequencyKHz * 1000, _IRREMOTE_ESP32_LEDC_RESOLUTION);
1740 sLastFrequencyKHz = aFrequencyKHz;
1745 ledcSetup(SEND_LEDC_CHANNEL, aFrequencyKHz * 1000, _IRREMOTE_ESP32_LEDC_RESOLUTION);
1746 # if defined(IR_SEND_PIN)
1752 if(sLastSendPin != 0) {
1754 ledcDetachPin(sLastSendPin);
1762 # endif // defined(SEND_PWM_BY_TIMER)
1767 #elif defined(ARDUINO_ARCH_SAMD)
1768 # if defined(SEND_PWM_BY_TIMER)
1769 #error PWM generation by hardware is not yet implemented for SAMD
1772 # if !defined(IR_SAMD_TIMER)
1773 # if defined(__SAMD51__)
1775 #define IR_SAMD_TIMER TC5
1776 #define IR_SAMD_TIMER_IRQ TC5_IRQn
1778 #define IR_SAMD_TIMER TC3
1779 #define IR_SAMD_TIMER_IRQ TC3_IRQn
1783 #define IR_SAMD_TIMER TC3
1784 #define IR_SAMD_TIMER_ID GCLK_CLKCTRL_ID_TCC2_TC3
1785 #define IR_SAMD_TIMER_IRQ TC3_IRQn
1790 NVIC_EnableIRQ (IR_SAMD_TIMER_IRQ);
1793 NVIC_DisableIRQ (IR_SAMD_TIMER_IRQ);
1811 TcCount16 *TC = (TcCount16*) IR_SAMD_TIMER;
1813 # if defined(__SAMD51__)
1815 # if defined(TC5_GCLK_ID)
1816 GCLK->PCHCTRL[TC5_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK0_Val | (1 << GCLK_PCHCTRL_CHEN_Pos);
1818 GCLK->PCHCTRL[TC3_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK0_Val | (1 << GCLK_PCHCTRL_CHEN_Pos);
1822 TC->CTRLA.reg &= ~TC_CTRLA_ENABLE;
1823 while (TC->SYNCBUSY.bit.ENABLE)
1826 TC->CTRLA.reg = TC_CTRLA_SWRST;
1828 while (TC->SYNCBUSY.bit.SWRST)
1837 TC->CTRLA.reg |= TC_CTRLA_MODE_COUNT16 | TC_WAVE_WAVEGEN_MFRQ | TC_CTRLA_PRESCALER_DIV16 | TC_CTRLA_ENABLE;
1841 REG_GCLK_CLKCTRL = (uint16_t)(GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | IR_SAMD_TIMER_ID);
1842 while (GCLK->STATUS.bit.SYNCBUSY == 1)
1846 TC->CTRLA.reg &= ~TC_CTRLA_ENABLE;
1848 while (TC->STATUS.bit.SYNCBUSY == 1)
1851 TC->CTRLA.reg = TC_CTRLA_SWRST;
1853 while (TC->CTRLA.bit.SWRST)
1862 TC->CTRLA.reg |= TC_CTRLA_MODE_COUNT16 | TC_CTRLA_WAVEGEN_MFRQ | TC_CTRLA_PRESCALER_DIV16 | TC_CTRLA_ENABLE;
1866 NVIC_DisableIRQ (IR_SAMD_TIMER_IRQ);
1867 NVIC_ClearPendingIRQ(IR_SAMD_TIMER_IRQ);
1868 NVIC_SetPriority(IR_SAMD_TIMER_IRQ, 0);
1869 NVIC_EnableIRQ(IR_SAMD_TIMER_IRQ);
1872 TC->INTENSET.bit.MC0 = 1;
1875 # if !defined(DISABLE_CODE_FOR_RECEIVER)
1876 # if defined(__SAMD51__) && defined(TC5)
1877 void TC5_Handler(
void)
1879 void TC3_Handler(
void)
1880 # endif // defined(__SAMD51__)
1882 TcCount16 *TC = (TcCount16*) IR_SAMD_TIMER;
1884 if (TC->INTFLAG.bit.MC0 == 1) {
1886 TC->INTFLAG.bit.MC0 = 1;
1890 # endif // !defined(DISABLE_CODE_FOR_RECEIVER)
1895 #elif defined(ARDUINO_ARCH_MBED) // Arduino Nano 33 BLE + Sparkfun Apollo3 + Nano RP2040 Connect
1897 mbed::Ticker s50usTimer;
1908 s50usTimer.detach();
1915 # if defined(SEND_PWM_BY_TIMER)
1916 #include "pins_arduino.h"
1918 # if defined(IR_SEND_PIN)
1919 mbed::PwmOut sPwmOutForSendPWM(digitalPinToPinName(
IR_SEND_PIN));
1921 mbed::PwmOut sPwmOutForSendPWM(digitalPinToPinName(
IrSender.
sendPin));
1923 uint8_t sIROutPuseWidth;
1924 uint8_t sIROutPuseWidthForHigh;
1927 sPwmOutForSendPWM.pulsewidth_us(sIROutPuseWidth);
1933 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
1934 sPwmOutForSendPWM.pulsewidth_us(sIROutPuseWidthForHigh);
1936 sPwmOutForSendPWM.pulsewidth_us(0);
1945 sIROutPuseWidthForHigh = 1000 / aFrequencyKHz;
1946 sPwmOutForSendPWM.period_us(sIROutPuseWidthForHigh);
1949 # endif // defined(SEND_PWM_BY_TIMER)
1957 #elif defined(ARDUINO_ARCH_RP2040) // Raspberry Pi Pico, Adafruit Feather RP2040, etc.
1958 #include "pico/time.h"
1960 repeating_timer_t s50usTimer;
1968 bool IRTimerInterruptHandlerHelper(repeating_timer_t*) {
1974 add_repeating_timer_us(-(
MICROS_PER_TICK), IRTimerInterruptHandlerHelper,
nullptr, &s50usTimer);
1977 cancel_repeating_timer(&s50usTimer);
1983 #define SEND_PWM_BY_TIMER // Disable carrier PWM generation in software and use (restricted) hardware PWM.
1985 # if defined(SEND_PWM_BY_TIMER)
1986 #include "hardware/pwm.h"
1987 #define USE_RP2040_NATIVE_COMMANDS
1989 # if defined(USE_RP2040_NATIVE_COMMANDS)
1990 uint sSliceNumberForSendPWM;
1991 uint sChannelNumberForSendPWM;
1992 uint sIROutPuseWidth;
1993 uint16_t sIROutPuseWidthForHigh;
2002 # if defined(USE_RP2040_NATIVE_COMMANDS)
2003 pwm_set_counter(sSliceNumberForSendPWM, 0);
2004 pwm_set_chan_level(sSliceNumberForSendPWM, sChannelNumberForSendPWM, sIROutPuseWidth);
2006 analogWriteFreq(sFrequency);
2007 # if defined(IR_SEND_PIN)
2016 # if defined(USE_RP2040_NATIVE_COMMANDS)
2017 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
2018 pwm_set_chan_level(sSliceNumberForSendPWM, sChannelNumberForSendPWM, sIROutPuseWidthForHigh);
2020 pwm_set_chan_level(sSliceNumberForSendPWM, sChannelNumberForSendPWM, 0);
2023 # if defined(IR_SEND_PIN)
2024 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
2030 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
2044 # if defined(USE_RP2040_NATIVE_COMMANDS)
2045 # if defined(IR_SEND_PIN)
2048 sSliceNumberForSendPWM = pwm_gpio_to_slice_num(
IR_SEND_PIN);
2049 sChannelNumberForSendPWM = pwm_gpio_to_channel(
IR_SEND_PIN);
2057 # if defined(IR_SEND_PIN)
2063 # if defined(USE_RP2040_NATIVE_COMMANDS)
2064 uint16_t tPWMWrapValue = (clock_get_hz(clk_sys)) / (aFrequencyKHz * 1000);
2065 pwm_config tPWMConfig = pwm_get_default_config();
2066 sIROutPuseWidthForHigh = tPWMWrapValue;
2067 pwm_config_set_wrap(&tPWMConfig, tPWMWrapValue - 1);
2068 pwm_init(sSliceNumberForSendPWM, &tPWMConfig,
false);
2070 pwm_set_chan_level(sSliceNumberForSendPWM, sChannelNumberForSendPWM, 0);
2071 pwm_set_enabled(sSliceNumberForSendPWM,
true);
2073 sFrequency = aFrequencyKHz * 1000;
2076 # endif // defined(SEND_PWM_BY_TIMER)
2081 #elif defined(NRF5) || defined(ARDUINO_ARCH_NRF52840) || defined(ARDUINO_ARCH_NRF52)
2082 # if defined(SEND_PWM_BY_TIMER)
2083 #error PWM generation by hardware not implemented for NRF5
2087 NVIC_EnableIRQ (TIMER2_IRQn);
2090 NVIC_DisableIRQ (TIMER2_IRQn);
2099 NRF_TIMER2->MODE = TIMER_MODE_MODE_Timer;
2100 NRF_TIMER2->TASKS_CLEAR = 1;
2101 NRF_TIMER2->PRESCALER = 4;
2102 NRF_TIMER2->BITMODE = TIMER_BITMODE_BITMODE_16Bit;
2104 NRF_TIMER2->CC[1] = 0;
2107 NRF_TIMER2->INTENSET = (TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos);
2108 NRF_TIMER2->TASKS_START = 1;
2113 #if !defined(DISABLE_CODE_FOR_RECEIVER)
2118 void TIMER2_IRQHandler(
void) {
2120 if ((NRF_TIMER2->EVENTS_COMPARE[0] != 0) && ((NRF_TIMER2->INTENSET & TIMER_INTENSET_COMPARE0_Msk) != 0)) {
2121 NRF_TIMER2->EVENTS_COMPARE[0] = 0;
2123 NRF_TIMER2->CC[0] += 50;
2136 #elif defined(__STM32F1__) || defined(ARDUINO_ARCH_STM32F1)
2137 #include <HardwareTimer.h>
2138 # if defined(SEND_PWM_BY_TIMER)
2139 #error PWM generation by hardware not implemented for STM32
2146 HardwareTimer s50usTimer(3);
2149 s50usTimer.resume();
2161 s50usTimer.setMode(TIMER_CH1, TIMER_OUTPUT_COMPARE);
2162 s50usTimer.setPrescaleFactor(1);
2165 s50usTimer.refresh();
2174 #elif defined(STM32F1xx) || defined(ARDUINO_ARCH_STM32)
2175 #include <HardwareTimer.h>
2176 # if defined(SEND_PWM_BY_TIMER)
2177 #error PWM generation by hardware not implemented for STM32
2185 HardwareTimer s50usTimer(TIM4);
2187 HardwareTimer s50usTimer(TIM2);
2191 s50usTimer.resume();
2205 s50usTimer.resume();
2212 #elif defined(PARTICLE)
2213 # ifndef __INTERVALTIMER_H__
2214 #include "SparkIntervalTimer.h"
2217 extern IntervalTimer timer;
2218 extern int ir_out_kHz;
2235 # if defined(SEND_PWM_BY_TIMER)
2236 # if defined(IR_SEND_PIN)
2259 # if defined(IR_SEND_PIN)
2264 ir_out_kHz = aFrequencyKHz;
2266 # endif // defined(SEND_PWM_BY_TIMER)
2268 #elif defined(VEGA_ARIES_V2) || defined(VEGA_ARIES_V3) || defined(VEGA_ARIES_IOT) || defined(VEGA_ARIES_MICRO)
2272 #define TIMER_RESET_INTR_PENDING
2273 #define TIMER_ENABLE_RECEIVE_INTR Timer.attachInterrupt(IRTimerInterruptHandler)
2274 #define TIMER_DISABLE_RECEIVE_INTR Timer.detachInterrupt()
2286 #define ISR() void IRTimerInterruptHandler(void)
2287 void IRTimerInterruptHandler(
void);
2291 Timer.attachInterrupt(IRTimerInterruptHandler);
2295 # if defined(SEND_PWM_BY_TIMER)
2296 #define ENABLE_SEND_PWM_BY_TIMER
2297 #define DISABLE_SEND_PWM_BY_TIMER
2300 TIMER_DISABLE_RECEIVE_INTR;
2301 # if defined(IR_SEND_PIN)
2306 (void) aFrequencyKHz;
2308 # endif // defined(SEND_PWM_BY_TIMER)
2314 #error Internal code configuration error, no timer functions implemented for this CPU / board
2325 #define ISR() void notImplemented(void)
2330 # if defined(SEND_PWM_BY_TIMER)
2338 # if defined(IR_SEND_PIN)
2343 (void) aFrequencyKHz;
2345 # endif // defined(SEND_PWM_BY_TIMER)
2347 #endif // defined(DOXYGEN / CPU_TYPES)
2351 #endif // _IR_TIMER_HPP