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__) || defined(__AVR_ATtiny1604__)
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_ATtiny1614__) || defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__) // e.g. TinyCore boards
192 # if !defined(IR_USE_AVR_TIMER_A) && !defined(IR_USE_AVR_TIMER_D)
193 #define IR_USE_AVR_TIMER_A // use this if you use megaTinyCore, Tone is on TCB and millis() on TCD
198 #elif defined(__AVR_ATmega8U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega8__)
199 # if !defined(IR_USE_AVR_TIMER1)
200 #define IR_USE_AVR_TIMER1 // send pin = pin C6
204 #elif defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny88__)
205 # if !defined(IR_USE_AVR_TIMER1)
206 #define IR_USE_AVR_TIMER1 // send pin = pin 6, no tone() available when using ATTinyCore
209 #elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)
210 # if !defined(IR_USE_AVR_TIMER1)
211 #define IR_USE_AVR_TIMER1 // send pin = pin PB1 / 8
213 #define USE_TIMER_CHANNEL_B
216 #elif defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
217 # if !defined(IR_USE_AVR_TIMER_TINY0) && !defined(IR_USE_AVR_TIMER_TINY1)
218 # if defined(ARDUINO_AVR_DIGISPARK) // tested with 16 and 8 MHz
219 #define IR_USE_AVR_TIMER_TINY0 // send pin = pin 1
223 #define IR_USE_AVR_TIMER_TINY1 // send pin = pin 4
230 #elif defined(ARDUINO_AVR_PROMICRO)
231 # if !defined(IR_USE_AVR_TIMER1) && !defined(IR_USE_AVR_TIMER3) && !defined(IR_USE_AVR_TIMER4_HS)
233 #define IR_USE_AVR_TIMER3 // send pin = pin 5
241 #elif defined(__AVR_AT90USB162__)
242 # if !defined(IR_USE_AVR_TIMER1)
243 #define IR_USE_AVR_TIMER1 // send pin = pin 17
247 #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
248 # if !defined(IR_USE_AVR_TIMER1) && !defined(IR_USE_AVR_TIMER2) && !defined(IR_USE_AVR_TIMER3)
250 #define IR_USE_AVR_TIMER2 // send pin = pin 1
255 #elif defined(__AVR_ATmega32U4__) && defined(TEENSYDUINO)
256 # if !defined(IR_USE_AVR_TIMER1) && !defined(IR_USE_AVR_TIMER3) && !defined(IR_USE_AVR_TIMER4_HS)
259 #define IR_USE_AVR_TIMER4_HS // send pin = pin 10 (Teensy 2.0 - physical pin: C7)
266 #elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2560__)
267 # if !defined(IR_USE_AVR_TIMER1)
268 #define IR_USE_AVR_TIMER1 // send pin = pin 13
274 #elif defined(__AVR_ATmega8515__) || defined(__AVR_ATmega162__)
275 # if !defined(IR_USE_AVR_TIMER1) && !defined(IR_USE_AVR_TIMER3)
276 #define IR_USE_AVR_TIMER1 // send pin = pin 13
284 #elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)
285 # if !defined(IR_USE_AVR_TIMER1) && !defined(IR_USE_AVR_TIMER2) && !defined(IR_USE_AVR_TIMER3)
287 #define IR_USE_AVR_TIMER2 // send pin = pin 14
292 #elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \
293 || defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \
294 || defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \
295 || defined(__AVR_ATmega164P__)
296 # if !defined(IR_USE_AVR_TIMER1) && !defined(IR_USE_AVR_TIMER2)
298 #define IR_USE_AVR_TIMER2 // send pin = pin 14
302 #elif defined(__AVR_ATmega8535__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__)
303 # if !defined(IR_USE_AVR_TIMER1)
304 #define IR_USE_AVR_TIMER1 // send pin = pin 13
314 #if defined(IR_USE_AVR_TIMER1)
317 #define TIMSK TIMSK1 // use the value of TIMSK1 for the statements below
321 TIMSK |= _BV(OCIE1A);
324 TIMSK &= ~_BV(OCIE1A);
327 # if defined(USE_TIMER_CHANNEL_B)
328 # if defined(TIMER1_COMPB_vect)
329 #define TIMER_INTR_NAME TIMER1_COMPB_vect
330 # elif defined(TIM1_COMPB_vect)
331 #define TIMER_INTR_NAME TIM1_COMPB_vect
334 # if defined(TIMER1_COMPA_vect)
335 #define TIMER_INTR_NAME TIMER1_COMPA_vect
336 # elif defined(TIM1_COMPA_vect)
337 #define TIMER_INTR_NAME TIM1_COMPA_vect
343 TCCR1B = _BV(WGM12) | _BV(CS10);
348 # if defined(SEND_PWM_BY_TIMER)
350 # if defined(CORE_OC1A_PIN)
351 #define IR_SEND_PIN CORE_OC1A_PIN // Teensy
353 # elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
354 #define IR_SEND_PIN 11 // Arduino Mega
357 # elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \
358 || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \
359 || defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \
360 || defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \
361 || defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \
362 || defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__) \
363 || defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) \
364 || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) \
365 || defined(__AVR_ATmega8515__) || defined(__AVR_ATmega162__)
366 #define IR_SEND_PIN 13
368 # elif defined(__AVR_ATtiny84__)
369 #define IR_SEND_PIN 6
371 # elif defined(__AVR_ATtiny88__)
372 #define IR_SEND_PIN 8
374 # elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)
378 # if defined(USE_TIMER_CHANNEL_B)
379 #define IR_SEND_PIN PIN_PB1 // OC1BU / PB1 / Pin9 at ATTinyCore
384 #define IR_SEND_PIN PIN_PB0 // OC1AU / PB1 / Pin8 at ATTinyCore
390 # else // defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)
391 #define IR_SEND_PIN 9 // OC1A Arduino Duemilanove, Diecimila, LilyPad, Sparkfun Pro Micro, Leonardo, MH-ET Tiny88 etc.
392 # endif // Set IR_SEND_PIN depending on CPU
394 # if defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)
396 # if defined(USE_TIMER_CHANNEL_B)
399 TCCR1A |= _BV(COM1B1);
400 TCCR1D |= _BV(OC1BU);
408 TCCR1A |= _BV(COM1A1);
409 TCCR1D |= _BV(OC1AU);
414 # endif // defined(USE_TIMER_CHANNEL_B)
418 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
419 # if defined(IR_SEND_PIN)
422 if (__builtin_constant_p(sendPin)) {
425 digitalWrite(sendPin, HIGH);
427 # endif // defined(IR_SEND_PIN)
428 # endif // defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
430 # else // defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)
431 # if defined(USE_TIMER_CHANNEL_B)
434 TCCR1A |= _BV(COM1B1);
437 TCCR1A &= ~(_BV(COM1B1));
438 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
439 # if defined(IR_SEND_PIN)
442 if (__builtin_constant_p(sendPin)) {
445 digitalWrite(sendPin, HIGH);
447 # endif // defined(IR_SEND_PIN)
448 # endif // defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
450 # else // defined(USE_TIMER_CHANNEL_B)
453 TCCR1A |= _BV(COM1A1);
456 TCCR1A &= ~(_BV(COM1A1));
457 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
458 # if defined(IR_SEND_PIN)
461 if (__builtin_constant_p(sendPin)) {
464 digitalWrite(sendPin, HIGH);
466 # endif // defined(IR_SEND_PIN)
467 # endif // defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
469 # endif // defined(USE_TIMER_CHANNEL_B)
471 # endif // defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)
480 # if (((F_CPU / 2000) / 38) < 256)
481 const uint16_t tPWMWrapValue = (F_CPU / 2000) / (aFrequencyKHz);
483 TCCR1B = _BV(WGM13) | _BV(CS10);
484 ICR1 = tPWMWrapValue - 1;
485 # if defined(USE_TIMER_CHANNEL_B)
492 const uint16_t tPWMWrapValue = ((F_CPU / 8) / 2000) / (aFrequencyKHz);
494 TCCR1B = _BV(WGM13) | _BV(CS11);
495 ICR1 = tPWMWrapValue - 1;
496 # if defined(USE_TIMER_CHANNEL_B)
502 # endif // if (((F_CPU / 2000) / 38) < 256)
504 # endif // defined(SEND_PWM_BY_TIMER) - Timer1
509 #elif defined(IR_USE_AVR_TIMER2)
512 TIMSK2 = _BV(OCIE2B);
517 #define TIMER_INTR_NAME TIMER2_COMPB_vect // We use TIMER2_COMPB_vect to be compatible with tone() library
518 #define TIMER_COUNT_TOP (F_CPU * MICROS_PER_TICK / MICROS_IN_ONE_SECOND)
521 # if (TIMER_COUNT_TOP < 256)
524 OCR2A = TIMER_COUNT_TOP;
525 OCR2B = TIMER_COUNT_TOP;
530 OCR2A = TIMER_COUNT_TOP / 8;
531 OCR2B = TIMER_COUNT_TOP / 8;
536 # if defined(SEND_PWM_BY_TIMER)
538 # if defined(CORE_OC2B_PIN)
539 #define IR_SEND_PIN CORE_OC2B_PIN // Teensy
541 # elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
542 #define IR_SEND_PIN 9 // Arduino Mega
544 # elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \
545 || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \
546 || defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \
547 || defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \
548 || defined(__AVR_ATmega164P__)
549 #define IR_SEND_PIN 14 // MightyCore, MegaCore
557 #define IR_SEND_PIN 3 // Arduino Uno Pin PD3, Duemilanove, Diecimila, LilyPad, etc
558 # endif // Set IR_SEND_PIN depending on CPU
562 TCCR2A |= _BV(COM2B1);
565 TCCR2A &= ~(_BV(COM2B1));
566 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
567 # if defined(IR_SEND_PIN)
570 if (__builtin_constant_p(sendPin)) {
573 digitalWrite(sendPin, HIGH);
575 # endif // defined(IR_SEND_PIN)
576 # endif // defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
586 # if (((F_CPU / 2000) / 38) < 256)
592 const uint16_t tPWMWrapValue = (F_CPU / 2000) / (aFrequencyKHz);
594 TCCR2B = _BV(WGM22) | _BV(CS20);
595 OCR2A = tPWMWrapValue - 1;
599 const uint16_t tPWMWrapValue = ((F_CPU / 8) / 2000) / (aFrequencyKHz);
601 TCCR2B = _BV(WGM22) | _BV(CS21);
602 OCR2A = tPWMWrapValue - 1;
607 # endif // defined(SEND_PWM_BY_TIMER)
612 #elif defined(IR_USE_AVR_TIMER3)
615 TIMSK3 = _BV(OCIE3B);
620 #define TIMER_INTR_NAME TIMER3_COMPB_vect
624 TCCR3B = _BV(WGM32) | _BV(CS30);
630 # if defined(SEND_PWM_BY_TIMER)
632 # if defined(CORE_OC3A_PIN)
633 #define IR_SEND_PIN CORE_OC3A_PIN // Teensy
635 # elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) \
636 || defined(__AVR_ATmega32U4__) || defined(ARDUINO_AVR_PROMICRO)
637 #define IR_SEND_PIN 5 // Arduino Mega, Arduino Leonardo, Sparkfun Pro Micro
639 # elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)
640 #define IR_SEND_PIN 6 // MightyCore, MegaCore
643 #error Please add OC3A pin number here
644 # endif // Set IR_SEND_PIN depending on CPU
648 TCCR3A |= _BV(COM3A1);
651 TCCR3A &= ~(_BV(COM3A1));
652 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
653 # if defined(IR_SEND_PIN)
656 if (__builtin_constant_p(sendPin)) {
659 digitalWrite(sendPin, HIGH);
661 # endif // defined(IR_SEND_PIN)
662 # endif // defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
670 # if F_CPU > 16000000
671 #error "Creating timer PWM with timer 3 is not supported for F_CPU > 16 MHz"
675 const uint16_t tPWMWrapValue = (F_CPU / 2000) / (aFrequencyKHz);
677 TCCR3B = _BV(WGM33) | _BV(CS30);
678 ICR3 = tPWMWrapValue - 1;
682 # endif // defined(SEND_PWM_BY_TIMER)
687 #elif defined(IR_USE_AVR_TIMER4)
689 TIMSK4 = _BV(OCIE4A);
694 #define TIMER_INTR_NAME TIMER4_COMPA_vect
698 TCCR4B = _BV(WGM42) | _BV(CS40);
703 # if defined(SEND_PWM_BY_TIMER)
705 # if defined(CORE_OC4A_PIN)
706 #define IR_SEND_PIN CORE_OC4A_PIN
707 # elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
708 #define IR_SEND_PIN 6 // Arduino Mega
710 #error Please add OC4A pin number here
715 TCCR4A |= _BV(COM4A1);
718 TCCR4A &= ~(_BV(COM4A1));
719 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
720 # if defined(IR_SEND_PIN)
723 if (__builtin_constant_p(sendPin)) {
726 digitalWrite(sendPin, HIGH);
728 # endif // defined(IR_SEND_PIN)
729 # endif // defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
733 # if F_CPU > 16000000
734 #error "Creating timer PWM with timer 4 is not supported for F_CPU > 16 MHz"
737 const uint16_t tPWMWrapValue = (F_CPU / 2000) / (aFrequencyKHz);
739 TCCR4B = _BV(WGM43) | _BV(CS40);
740 ICR4 = tPWMWrapValue - 1;
744 # endif // defined(SEND_PWM_BY_TIMER)
749 #elif defined(IR_USE_AVR_TIMER4_HS)
757 #define TIMER_INTR_NAME TIMER4_OVF_vect
771 # if defined(SEND_PWM_BY_TIMER)
772 # if defined(CORE_OC4A_PIN)
773 #define IR_SEND_PIN CORE_OC4A_PIN // Teensy 2.0
774 # elif defined(ARDUINO_AVR_PROMICRO)
775 #define IR_SEND_PIN 5 // Sparkfun Pro Micro
776 # elif defined(__AVR_ATmega32U4__)
777 #define IR_SEND_PIN 13 // Leonardo
779 #error Please add OC4A pin number here
782 # if defined(ARDUINO_AVR_PROMICRO) // Sparkfun Pro Micro
785 TCCR4A |= _BV(COM4A0);
788 TCCR4A &= ~(_BV(COM4A0));
789 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
790 # if defined(IR_SEND_PIN)
793 if (__builtin_constant_p(sendPin)) {
796 digitalWrite(sendPin, HIGH);
798 # endif // defined(IR_SEND_PIN)
799 # endif // defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
805 TCCR4A |= _BV(COM4A1);
809 TCCR4A &= ~(_BV(COM4A1));
810 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
811 # if defined(IR_SEND_PIN)
814 if (__builtin_constant_p(sendPin)) {
817 digitalWrite(sendPin, HIGH);
819 # endif // defined(IR_SEND_PIN)
820 # endif // defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
830 #error "Creating timer PWM with timer 4 HS is not supported for F_CPU > 16 MHz"
834 const uint16_t tPWMWrapValue = ((F_CPU / 2000) / (aFrequencyKHz)) - 1;
835 TCCR4A = (1 << PWM4A);
838 TCCR4D = (1 << WGM40);
840 TC4H = tPWMWrapValue >> 8;
841 OCR4C = tPWMWrapValue;
846 # endif // defined(SEND_PWM_BY_TIMER)
851 #elif defined(IR_USE_AVR_TIMER5)
854 TIMSK5 = _BV(OCIE5A);
859 #define TIMER_INTR_NAME TIMER5_COMPA_vect
863 TCCR5B = _BV(WGM52) | _BV(CS50);
868 # if defined(SEND_PWM_BY_TIMER)
869 # if defined(CORE_OC5A_PIN)
870 #define IR_SEND_PIN CORE_OC5A_PIN
871 # elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
872 #define IR_SEND_PIN 46 // Arduino Mega
874 #error Please add OC5A pin number here
879 TCCR5A |= _BV(COM5A1);
882 TCCR5A &= ~(_BV(COM5A1));
883 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
884 # if defined(IR_SEND_PIN)
887 if (__builtin_constant_p(sendPin)) {
890 digitalWrite(sendPin, HIGH);
892 # endif // defined(IR_SEND_PIN)
893 # endif // defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
902 #error "Creating timer PWM with timer 5 is not supported for F_CPU > 16 MHz"
906 const uint16_t tPWMWrapValue = (F_CPU / 2000) / (aFrequencyKHz);
908 TCCR5B = _BV(WGM53) | _BV(CS50);
909 ICR5 = tPWMWrapValue - 1;
913 # endif // defined(SEND_PWM_BY_TIMER)
918 #elif defined(IR_USE_AVR_TIMER_TINY0)
921 TIMSK |= _BV(OCIE0A);
924 TIMSK &= ~(_BV(OCIE0A));
926 #define TIMER_INTR_NAME TIMER0_COMPA_vect
928 #define TIMER_COUNT_TOP (F_CPU * MICROS_PER_TICK / MICROS_IN_ONE_SECOND)
931 # if (TIMER_COUNT_TOP < 256)
934 OCR0A = TIMER_COUNT_TOP;
939 OCR0A = TIMER_COUNT_TOP / 8;
944 # if defined(SEND_PWM_BY_TIMER)
945 #define IR_SEND_PIN 1
949 TCCR0A |= _BV(COM0B1);
952 TCCR0A &= ~(_BV(COM0B1));
953 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
954 # if defined(IR_SEND_PIN)
957 if (__builtin_constant_p(sendPin)) {
960 digitalWrite(sendPin, HIGH);
962 # endif // defined(IR_SEND_PIN)
963 # endif // defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
971 # if F_CPU > 16000000
972 #error "Creating timer PWM with timer TINY0 is not supported for F_CPU > 16 MHz"
976 const uint16_t tPWMWrapValue = (F_CPU / 2000) / (aFrequencyKHz);
978 TCCR0B = _BV(WGM02) | _BV(CS00);
979 OCR0A = tPWMWrapValue - 1;
983 # endif // defined(SEND_PWM_BY_TIMER)
988 #elif defined(IR_USE_AVR_TIMER_TINY1)
991 TIMSK |= _BV(OCIE1B);
994 TIMSK &= ~(_BV(OCIE1B));
996 #define TIMER_INTR_NAME TIMER1_COMPB_vect
998 #define TIMER_COUNT_TOP (F_CPU * MICROS_PER_TICK / MICROS_IN_ONE_SECOND)
1001 # if (TIMER_COUNT_TOP < 256)
1002 TCCR1 = _BV(CTC1) | _BV(CS10);
1004 OCR1C = TIMER_COUNT_TOP;
1007 TCCR1 = _BV(CTC1) | _BV(CS12);
1009 OCR1C = TIMER_COUNT_TOP / 8;
1014 # if defined(SEND_PWM_BY_TIMER)
1015 #define IR_SEND_PIN 4
1019 GTCCR |= _BV(PWM1B) | _BV(COM1B0);
1022 GTCCR &= ~(_BV(PWM1B) | _BV(COM1B0));
1023 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
1024 # if defined(IR_SEND_PIN)
1027 if (__builtin_constant_p(sendPin)) {
1030 digitalWrite(sendPin, HIGH);
1032 # endif // defined(IR_SEND_PIN)
1033 # endif // defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
1043 # if (((F_CPU / 1000) / 38) < 256)
1044 const uint16_t tPWMWrapValue = (F_CPU / 1000) / (aFrequencyKHz);
1045 TCCR1 = _BV(CTC1) | _BV(CS10);
1046 OCR1C = tPWMWrapValue - 1;
1049 GTCCR = _BV(PWM1B) | _BV(COM1B0);
1051 const uint16_t tPWMWrapValue = ((F_CPU / 2) / 1000) / (aFrequencyKHz);
1052 TCCR1 = _BV(CTC1) | _BV(CS11);
1053 OCR1C = tPWMWrapValue - 1;
1056 GTCCR = _BV(PWM1B) | _BV(COM1B0);
1059 # endif // defined(SEND_PWM_BY_TIMER)
1064 #elif defined(IR_USE_AVR_TIMER_A)
1065 #define TIMER_REQUIRES_RESET_INTR_PENDING
1067 TCA0.SINGLE.INTFLAGS = TCA_SINGLE_OVF_bm;
1070 TCA0.SINGLE.INTCTRL = TCA_SINGLE_OVF_bm;
1073 TCA0.SINGLE.INTCTRL &= ~(TCA_SINGLE_OVF_bm);
1075 #define TIMER_INTR_NAME TCA0_OVF_vect
1082 TCA0.SINGLE.CTRLD = 0;
1083 TCA0.SINGLE.CTRLB = TCA_SINGLE_WGMODE_NORMAL_gc;
1085 TCA0.SINGLE.CTRLA = TCA_SINGLE_CLKSEL_DIV1_gc | TCA_SINGLE_ENABLE_bm;
1088 # if defined(SEND_PWM_BY_TIMER)
1089 #error "No support for hardware PWM generation for ATtiny3216/17 etc."
1090 # endif // defined(SEND_PWM_BY_TIMER)
1095 #elif defined(IR_USE_AVR_TIMER_B)
1098 #define TIMER_REQUIRES_RESET_INTR_PENDING
1100 TCB0.INTFLAGS = TCB_CAPT_bm;
1103 TCB0.INTCTRL = TCB_CAPT_bm;
1106 TCB0.INTCTRL &= ~(TCB_CAPT_bm);
1108 #define TIMER_INTR_NAME TCB0_INT_vect
1111 TCB0.CTRLB = (TCB_CNTMODE_INT_gc);
1113 TCB0.INTFLAGS = TCB_CAPT_bm;
1114 TCB0.CTRLA = (TCB_CLKSEL_CLKDIV1_gc) | (TCB_ENABLE_bm);
1117 # if defined(SEND_PWM_BY_TIMER)
1118 # if defined(__AVR_ATmega4808__) || defined(__AVR_ATmega4809__)
1119 #define IR_SEND_PIN 6 // PF4 on ATmega4809 / Nano Every (see pins_arduino.h digital_pin_to_timer)
1121 #error SEND_PWM_BY_TIMER not yet supported for this CPU
1126 TCB0.CTRLB |= TCB_CCMPEN_bm;
1129 TCB0.CTRLB &= ~(TCB_CCMPEN_bm);
1130 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
1131 # if defined(IR_SEND_PIN)
1134 if (__builtin_constant_p(sendPin)) {
1137 digitalWrite(sendPin, HIGH);
1139 # endif // defined(IR_SEND_PIN)
1140 # endif // defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
1148 #if F_CPU > 16000000
1150 #error "Creating timer PWM with timer TCB0 is not possible for F_CPU > 16 MHz"
1154 const uint16_t tPWMWrapValue = (F_CPU / 2000) / (aFrequencyKHz);
1155 TCB0.CTRLB = TCB_CNTMODE_PWM8_gc;
1156 TCB0.CCMPL = tPWMWrapValue - 1;
1158 TCB0.CTRLA = (TCB_CLKSEL_CLKDIV2_gc) | (TCB_ENABLE_bm);
1161 # endif // defined(SEND_PWM_BY_TIMER)
1166 #elif defined(IR_USE_AVR_TIMER_D)
1168 #define TIMER_REQUIRES_RESET_INTR_PENDING
1170 TCD0.INTFLAGS = TCD_OVF_bm;
1173 TCD0.INTCTRL = TCD_OVF_bm;
1178 #define TIMER_INTR_NAME TCD0_OVF_vect
1182 TCD0.CTRLB = TCD_WGMODE_ONERAMP_gc;
1186 _PROTECTED_WRITE(TCD0.FAULTCTRL, 0);
1188 TCD0.INTFLAGS = TCD_OVF_bm;
1192 TCD0.CTRLA = TCD_ENABLE_bm | TCD_CLKSEL_SYSCLK_gc | TCD_CNTPRES_DIV1_gc;
1195 # if defined(SEND_PWM_BY_TIMER)
1196 #define IR_SEND_PIN 13
1198 void timerEnableSendPWM() {
1200 _PROTECTED_WRITE(TCD0.FAULTCTRL, FUSE_CMPAEN_bm);
1202 TCD0.CTRLA = TCD_ENABLE_bm | TCD_CLKSEL_SYSCLK_gc | TCD_CNTPRES_DIV1_gc;
1206 timerEnableSendPWM();
1210 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
1211 # if defined(IR_SEND_PIN)
1214 if (__builtin_constant_p(sendPin)) {
1217 digitalWrite(sendPin, HIGH);
1219 # endif // defined(IR_SEND_PIN)
1220 # endif // defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
1230 const uint16_t tPWMWrapValue = (F_CPU / 1000) / (aFrequencyKHz);
1234 TCD0.CTRLB = TCD_WGMODE_ONERAMP_gc;
1237 TCD0.CMPBCLR = tPWMWrapValue - 1;
1243 TCD0.INTFLAGS = TCD_OVF_bm;
1244 TCD0.INTCTRL = TCD_OVF_bm;
1247 # endif // defined(SEND_PWM_BY_TIMER)
1250 #error Internal code configuration error, no timer functions implemented for this AVR CPU / board
1251 #endif //defined(IR_USE_AVR_TIMER*)
1259 #elif defined(ARDUINO_ARCH_RENESAS)
1260 #include "FspTimer.h"
1261 FspTimer s50usTimer;
1269 void IRTimerInterruptHandlerHelper(timer_callback_args_t __attribute((unused)) *p_args) {
1282 uint8_t tTimerType = GPT_TIMER;
1283 int8_t tIndex = FspTimer::get_available_timer(tTimerType);
1284 if (tIndex < 0 || tTimerType != GPT_TIMER) {
1286 tIndex = FspTimer::get_available_timer(tTimerType,
true);
1293 IRTimerInterruptHandlerHelper);
1294 s50usTimer.setup_overflow_irq();
1299 # if defined(SEND_PWM_BY_TIMER)
1300 #error PWM generation by hardware not yet implemented for Arduino Uno R4
1311 # if defined(IR_SEND_PIN)
1320 #elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
1323 #define TIMER_REQUIRES_RESET_INTR_PENDING
1325 uint8_t tmp __attribute__((unused)) = CMT_MSC;
1329 NVIC_ENABLE_IRQ(IRQ_CMT);
1330 NVIC_SET_PRIORITY(IRQ_CMT, 48);
1333 NVIC_DISABLE_IRQ(IRQ_CMT);
1336 #define TIMER_INTR_NAME cmt_isr
1340 #define ISR(f) void f(void)
1342 #define CMT_PPS_DIV ((F_BUS + 7999999) / 8000000)
1343 # if F_BUS < 8000000
1344 #error IRremote requires at least 8 MHz on Teensy 3.x
1348 SIM_SCGC4 |= SIM_SCGC4_CMT;
1349 CMT_PPS = CMT_PPS_DIV - 1;
1355 CMT_CMD4 = (F_BUS / 160000 + CMT_PPS_DIV / 2) / CMT_PPS_DIV - 31;
1360 # if defined(SEND_PWM_BY_TIMER)
1361 #define IR_SEND_PIN 5
1365 CORE_PIN5_CONFIG = PORT_PCR_MUX(2) | PORT_PCR_DSE | PORT_PCR_SRE;
1370 CORE_PIN5_CONFIG = PORT_PCR_MUX(1) | PORT_PCR_DSE | PORT_PCR_SRE;
1380 # if defined(IR_SEND_PIN)
1386 SIM_SCGC4 |= SIM_SCGC4_CMT;
1387 SIM_SOPT2 |= SIM_SOPT2_PTD7PAD;
1388 CMT_PPS = CMT_PPS_DIV - 1;
1389 CMT_CGH1 = ((F_BUS / CMT_PPS_DIV / 3000) + ((aFrequencyKHz) / 2)) / (aFrequencyKHz);
1390 CMT_CGL1 = ((F_BUS / CMT_PPS_DIV / 1500) + ((aFrequencyKHz) / 2)) / (aFrequencyKHz);
1398 # endif // defined(SEND_PWM_BY_TIMER)
1403 #elif defined(__MKL26Z64__)
1406 #define TIMER_REQUIRES_RESET_INTR_PENDING
1408 FTM1_SC |= FTM_SC_TOF;
1411 NVIC_ENABLE_IRQ(IRQ_FTM1);
1412 NVIC_SET_PRIORITY(IRQ_FTM1, 0);
1415 NVIC_DISABLE_IRQ(IRQ_FTM1);
1417 #define TIMER_INTR_NAME ftm1_isr
1421 #define ISR(f) void f(void)
1424 SIM_SCGC6 |= SIM_SCGC6_TPM1;
1427 FTM1_MOD = (F_PLL / 40000) - 1;
1429 FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0) | FTM_SC_TOF | FTM_SC_TOIE;
1432 # if defined(SEND_PWM_BY_TIMER)
1433 #define IR_SEND_PIN 16
1437 CORE_PIN16_CONFIG = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
1440 CORE_PIN16_CONFIG = PORT_PCR_MUX(1) | PORT_PCR_SRE;
1449 # if defined(IR_SEND_PIN)
1455 SIM_SCGC6 |= SIM_SCGC6_TPM1;
1458 FTM1_MOD = ((F_PLL / 2000) / aFrequencyKHz) - 1;
1459 FTM1_C0V = ((F_PLL / 6000) / aFrequencyKHz) - 1;
1460 FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0);
1462 # endif // defined(SEND_PWM_BY_TIMER)
1467 #elif defined(__IMXRT1062__)
1472 #define TIMER_REQUIRES_RESET_INTR_PENDING
1474 FLEXPWM1_SM3STS = FLEXPWM_SMSTS_RF;
1477 attachInterruptVector(IRQ_FLEXPWM1_3, pwm1_3_isr);
1478 FLEXPWM1_SM3STS = FLEXPWM_SMSTS_RF;
1479 FLEXPWM1_SM3INTEN = FLEXPWM_SMINTEN_RIE;
1480 NVIC_ENABLE_IRQ (IRQ_FLEXPWM1_3), NVIC_SET_PRIORITY(IRQ_FLEXPWM1_3, 48);
1483 NVIC_DISABLE_IRQ (IRQ_FLEXPWM1_3);
1485 #define TIMER_INTR_NAME pwm1_3_isr
1489 #define ISR(f) void (f)(void)
1492 uint32_t period = (float) F_BUS_ACTUAL * (
float) (
MICROS_PER_TICK) * 0.0000005f;
1493 uint32_t prescale = 0;
1494 while (period > 32767) {
1495 period = period >> 1;
1499 FLEXPWM1_FCTRL0 |= FLEXPWM_FCTRL0_FLVL(8);
1500 FLEXPWM1_FSTS0 = 0x0008;
1501 FLEXPWM1_MCTRL |= FLEXPWM_MCTRL_CLDOK(8);
1502 FLEXPWM1_SM3CTRL2 = FLEXPWM_SMCTRL2_INDEP;
1503 FLEXPWM1_SM3CTRL = FLEXPWM_SMCTRL_HALF | FLEXPWM_SMCTRL_PRSC(prescale);
1504 FLEXPWM1_SM3INIT = -period;
1505 FLEXPWM1_SM3VAL0 = 0;
1506 FLEXPWM1_SM3VAL1 = period;
1507 FLEXPWM1_SM3VAL2 = 0;
1508 FLEXPWM1_SM3VAL3 = 0;
1509 FLEXPWM1_SM3VAL4 = 0;
1510 FLEXPWM1_SM3VAL5 = 0;
1511 FLEXPWM1_MCTRL |= FLEXPWM_MCTRL_LDOK(8) | FLEXPWM_MCTRL_RUN(8);
1514 # if defined(SEND_PWM_BY_TIMER)
1515 #define IR_SEND_PIN 7
1517 FLEXPWM1_OUTEN |= FLEXPWM_OUTEN_PWMA_EN(8);
1518 IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_00 = 6;
1522 IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_00 = 5;
1523 FLEXPWM1_OUTEN &= ~FLEXPWM_OUTEN_PWMA_EN(8);
1532 # if defined(IR_SEND_PIN)
1538 uint32_t period = (float) F_BUS_ACTUAL / (
float) ((aFrequencyKHz) * 2000);
1539 uint32_t prescale = 0;
1540 while (period > 32767) {
1541 period = period >> 1;
1545 FLEXPWM1_FCTRL0 |= FLEXPWM_FCTRL0_FLVL(8);
1546 FLEXPWM1_FSTS0 = 0x0008;
1547 FLEXPWM1_MCTRL |= FLEXPWM_MCTRL_CLDOK(8);
1548 FLEXPWM1_SM3CTRL2 = FLEXPWM_SMCTRL2_INDEP;
1549 FLEXPWM1_SM3CTRL = FLEXPWM_SMCTRL_HALF | FLEXPWM_SMCTRL_PRSC(prescale);
1550 FLEXPWM1_SM3INIT = -period;
1551 FLEXPWM1_SM3VAL0 = 0;
1552 FLEXPWM1_SM3VAL1 = period;
1553 FLEXPWM1_SM3VAL2 = -(period / 3);
1554 FLEXPWM1_SM3VAL3 = period / 3;
1555 FLEXPWM1_SM3VAL4 = 0;
1556 FLEXPWM1_SM3VAL5 = 0;
1557 FLEXPWM1_MCTRL |= FLEXPWM_MCTRL_LDOK(8) | FLEXPWM_MCTRL_RUN(8);
1559 # endif // defined(SEND_PWM_BY_TIMER)
1564 #elif defined(ESP8266)
1565 # if defined(SEND_PWM_BY_TIMER)
1566 #error "No support for hardware PWM generation for ESP8266"
1567 # endif // defined(SEND_PWM_BY_TIMER)
1578 timer1_detachInterrupt();
1588 timer1_enable(TIM_DIV16, TIM_EDGE, TIM_LOOP);
1597 #elif defined(ESP32)
1598 # if !defined(ESP_ARDUINO_VERSION)
1599 #define ESP_ARDUINO_VERSION 0x010101 // Version 1.1.1
1604 hw_timer_t *s50usTimer =
nullptr;
1605 #define _IRREMOTE_ESP32_LEDC_RESOLUTION 8
1606 #define _IRREMOTE_ESP32_LEDC_RESOLUTION_MAX_PWM_VALUE 255
1609 # if ESP_ARDUINO_VERSION < (3 << 16 | 0 << 8 | 0) && !defined(SEND_LEDC_CHANNEL) // works also in case ESP_ARDUINO_VERSION_VAL is not defined
1610 #define SEND_LEDC_CHANNEL 0 // The channel used for PWM 0 to 7 are high speed PWM channels
1615 # if ESP_ARDUINO_VERSION >= (3 << 16 | 0 << 8 | 0)
1616 timerStart(s50usTimer);
1618 timerAlarmEnable(s50usTimer);
1623 # if ESP_ARDUINO_VERSION < (2 << 16 | 0 << 8 | 2)
1628 if (s50usTimer !=
nullptr) {
1629 timerDetachInterrupt(s50usTimer);
1630 timerEnd(s50usTimer);
1636 if (s50usTimer !=
nullptr) {
1638 # if ESP_ARDUINO_VERSION >= (3 << 16 | 0 << 8 | 0)
1639 timerStop(s50usTimer);
1641 timerAlarmDisable(s50usTimer);
1652 # if !defined(DISABLE_CODE_FOR_RECEIVER) // Otherwise the &IRReceiveTimerInterruptHandler is referenced, but not available
1657 if (s50usTimer ==
nullptr) {
1659 # if ESP_ARDUINO_VERSION >= (3 << 16 | 0 << 8 | 0)
1660 s50usTimer = timerBegin(1000000);
1661 timerStop(s50usTimer);
1665 s50usTimer = timerBegin(1, 80,
true);
1674 uint8_t sLastSendPin = 0;
1676 # if defined(SEND_PWM_BY_TIMER)
1679 # if ESP_ARDUINO_VERSION >= (3 << 16 | 0 << 8 | 0)
1680 # if defined(IR_SEND_PIN)
1692 # if ESP_ARDUINO_VERSION >= (3 << 16 | 0 << 8 | 0)
1693 # if defined(IR_SEND_PIN)
1694 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
1695 ledcWrite(
IR_SEND_PIN, _IRREMOTE_ESP32_LEDC_RESOLUTION_MAX_PWM_VALUE);
1700 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
1701 ledcWrite(
IrSender.
sendPin, _IRREMOTE_ESP32_LEDC_RESOLUTION_MAX_PWM_VALUE);
1708 ledcWrite(SEND_LEDC_CHANNEL, 0);
1718 # if ESP_ARDUINO_VERSION >= (3 << 16 | 0 << 8 | 0)
1719 # if defined(IR_SEND_PIN)
1720 if(sLastSendPin == 0){
1721 ledcAttach(
IR_SEND_PIN, aFrequencyKHz * 1000, _IRREMOTE_ESP32_LEDC_RESOLUTION);
1728 ledcAttach(
IrSender.
sendPin, aFrequencyKHz * 1000, _IRREMOTE_ESP32_LEDC_RESOLUTION);
1733 ledcSetup(SEND_LEDC_CHANNEL, aFrequencyKHz * 1000, _IRREMOTE_ESP32_LEDC_RESOLUTION);
1734 # if defined(IR_SEND_PIN)
1745 # endif // defined(SEND_PWM_BY_TIMER)
1750 #elif defined(ARDUINO_ARCH_SAMD)
1751 # if defined(SEND_PWM_BY_TIMER)
1752 #error PWM generation by hardware is not yet implemented for SAMD
1755 # if !defined(IR_SAMD_TIMER)
1756 # if defined(__SAMD51__)
1758 #define IR_SAMD_TIMER TC5
1759 #define IR_SAMD_TIMER_IRQ TC5_IRQn
1761 #define IR_SAMD_TIMER TC3
1762 #define IR_SAMD_TIMER_IRQ TC3_IRQn
1766 #define IR_SAMD_TIMER TC3
1767 #define IR_SAMD_TIMER_ID GCLK_CLKCTRL_ID_TCC2_TC3
1768 #define IR_SAMD_TIMER_IRQ TC3_IRQn
1773 NVIC_EnableIRQ (IR_SAMD_TIMER_IRQ);
1776 NVIC_DisableIRQ (IR_SAMD_TIMER_IRQ);
1794 TcCount16 *TC = (TcCount16*) IR_SAMD_TIMER;
1796 # if defined(__SAMD51__)
1798 # if defined(TC5_GCLK_ID)
1799 GCLK->PCHCTRL[TC5_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK0_Val | (1 << GCLK_PCHCTRL_CHEN_Pos);
1801 GCLK->PCHCTRL[TC3_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK0_Val | (1 << GCLK_PCHCTRL_CHEN_Pos);
1805 TC->CTRLA.reg &= ~TC_CTRLA_ENABLE;
1806 while (TC->SYNCBUSY.bit.ENABLE)
1809 TC->CTRLA.reg = TC_CTRLA_SWRST;
1811 while (TC->SYNCBUSY.bit.SWRST)
1820 TC->CTRLA.reg |= TC_CTRLA_MODE_COUNT16 | TC_WAVE_WAVEGEN_MFRQ | TC_CTRLA_PRESCALER_DIV16 | TC_CTRLA_ENABLE;
1824 REG_GCLK_CLKCTRL = (uint16_t)(GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | IR_SAMD_TIMER_ID);
1825 while (GCLK->STATUS.bit.SYNCBUSY == 1)
1829 TC->CTRLA.reg &= ~TC_CTRLA_ENABLE;
1831 while (TC->STATUS.bit.SYNCBUSY == 1)
1834 TC->CTRLA.reg = TC_CTRLA_SWRST;
1836 while (TC->CTRLA.bit.SWRST)
1845 TC->CTRLA.reg |= TC_CTRLA_MODE_COUNT16 | TC_CTRLA_WAVEGEN_MFRQ | TC_CTRLA_PRESCALER_DIV16 | TC_CTRLA_ENABLE;
1849 NVIC_DisableIRQ (IR_SAMD_TIMER_IRQ);
1850 NVIC_ClearPendingIRQ(IR_SAMD_TIMER_IRQ);
1851 NVIC_SetPriority(IR_SAMD_TIMER_IRQ, 0);
1852 NVIC_EnableIRQ(IR_SAMD_TIMER_IRQ);
1855 TC->INTENSET.bit.MC0 = 1;
1858 # if !defined(DISABLE_CODE_FOR_RECEIVER)
1859 # if defined(__SAMD51__) && defined(TC5)
1860 void TC5_Handler(
void)
1862 void TC3_Handler(
void)
1863 # endif // defined(__SAMD51__)
1865 TcCount16 *TC = (TcCount16*) IR_SAMD_TIMER;
1867 if (TC->INTFLAG.bit.MC0 == 1) {
1869 TC->INTFLAG.bit.MC0 = 1;
1873 # endif // !defined(DISABLE_CODE_FOR_RECEIVER)
1878 #elif defined(ARDUINO_ARCH_MBED) // Arduino Nano 33 BLE + Sparkfun Apollo3 + Nano RP2040 Connect
1880 mbed::Ticker s50usTimer;
1891 s50usTimer.detach();
1898 # if defined(SEND_PWM_BY_TIMER)
1899 #include "pins_arduino.h"
1901 # if defined(IR_SEND_PIN)
1902 mbed::PwmOut sPwmOutForSendPWM(digitalPinToPinName(
IR_SEND_PIN));
1904 mbed::PwmOut sPwmOutForSendPWM(digitalPinToPinName(
IrSender.
sendPin));
1906 uint8_t sIROutPuseWidth;
1907 uint8_t sIROutPuseWidthForHigh;
1910 sPwmOutForSendPWM.pulsewidth_us(sIROutPuseWidth);
1916 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
1917 sPwmOutForSendPWM.pulsewidth_us(sIROutPuseWidthForHigh);
1919 sPwmOutForSendPWM.pulsewidth_us(0);
1928 sIROutPuseWidthForHigh = 1000 / aFrequencyKHz;
1929 sPwmOutForSendPWM.period_us(sIROutPuseWidthForHigh);
1932 # endif // defined(SEND_PWM_BY_TIMER)
1940 #elif defined(ARDUINO_ARCH_RP2040) // Raspberry Pi Pico, Adafruit Feather RP2040, etc.
1941 #include "pico/time.h"
1943 repeating_timer_t s50usTimer;
1951 bool IRTimerInterruptHandlerHelper(repeating_timer_t*) {
1957 add_repeating_timer_us(-(
MICROS_PER_TICK), IRTimerInterruptHandlerHelper,
nullptr, &s50usTimer);
1960 cancel_repeating_timer(&s50usTimer);
1966 #define SEND_PWM_BY_TIMER // Disable carrier PWM generation in software and use (restricted) hardware PWM.
1968 # if defined(SEND_PWM_BY_TIMER)
1969 #include "hardware/pwm.h"
1970 #define USE_RP2040_NATIVE_COMMANDS
1972 # if defined(USE_RP2040_NATIVE_COMMANDS)
1973 uint sSliceNumberForSendPWM;
1974 uint sChannelNumberForSendPWM;
1975 uint sIROutPuseWidth;
1976 uint16_t sIROutPuseWidthForHigh;
1985 # if defined(USE_RP2040_NATIVE_COMMANDS)
1986 pwm_set_counter(sSliceNumberForSendPWM, 0);
1987 pwm_set_chan_level(sSliceNumberForSendPWM, sChannelNumberForSendPWM, sIROutPuseWidth);
1989 analogWriteFreq(sFrequency);
1990 # if defined(IR_SEND_PIN)
1999 # if defined(USE_RP2040_NATIVE_COMMANDS)
2000 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
2001 pwm_set_chan_level(sSliceNumberForSendPWM, sChannelNumberForSendPWM, sIROutPuseWidthForHigh);
2003 pwm_set_chan_level(sSliceNumberForSendPWM, sChannelNumberForSendPWM, 0);
2006 # if defined(IR_SEND_PIN)
2007 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
2013 # if defined(USE_ACTIVE_LOW_OUTPUT_FOR_SEND_PIN)
2027 # if defined(USE_RP2040_NATIVE_COMMANDS)
2028 # if defined(IR_SEND_PIN)
2031 sSliceNumberForSendPWM = pwm_gpio_to_slice_num(
IR_SEND_PIN);
2032 sChannelNumberForSendPWM = pwm_gpio_to_channel(
IR_SEND_PIN);
2040 # if defined(IR_SEND_PIN)
2046 # if defined(USE_RP2040_NATIVE_COMMANDS)
2047 uint16_t tPWMWrapValue = (clock_get_hz(clk_sys)) / (aFrequencyKHz * 1000);
2048 pwm_config tPWMConfig = pwm_get_default_config();
2049 sIROutPuseWidthForHigh = tPWMWrapValue;
2050 pwm_config_set_wrap(&tPWMConfig, tPWMWrapValue - 1);
2051 pwm_init(sSliceNumberForSendPWM, &tPWMConfig,
false);
2053 pwm_set_chan_level(sSliceNumberForSendPWM, sChannelNumberForSendPWM, 0);
2054 pwm_set_enabled(sSliceNumberForSendPWM,
true);
2056 sFrequency = aFrequencyKHz * 1000;
2059 # endif // defined(SEND_PWM_BY_TIMER)
2064 #elif defined(NRF5) || defined(ARDUINO_ARCH_NRF52840) || defined(ARDUINO_ARCH_NRF52)
2065 # if defined(SEND_PWM_BY_TIMER)
2066 #error PWM generation by hardware not implemented for NRF5
2070 NVIC_EnableIRQ (TIMER2_IRQn);
2073 NVIC_DisableIRQ (TIMER2_IRQn);
2082 NRF_TIMER2->MODE = TIMER_MODE_MODE_Timer;
2083 NRF_TIMER2->TASKS_CLEAR = 1;
2084 NRF_TIMER2->PRESCALER = 4;
2085 NRF_TIMER2->BITMODE = TIMER_BITMODE_BITMODE_16Bit;
2087 NRF_TIMER2->CC[1] = 0;
2090 NRF_TIMER2->INTENSET = (TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos);
2091 NRF_TIMER2->TASKS_START = 1;
2096 #if !defined(DISABLE_CODE_FOR_RECEIVER)
2101 void TIMER2_IRQHandler(
void) {
2103 if ((NRF_TIMER2->EVENTS_COMPARE[0] != 0) && ((NRF_TIMER2->INTENSET & TIMER_INTENSET_COMPARE0_Msk) != 0)) {
2104 NRF_TIMER2->EVENTS_COMPARE[0] = 0;
2106 NRF_TIMER2->CC[0] += 50;
2119 #elif defined(__STM32F1__) || defined(ARDUINO_ARCH_STM32F1)
2120 #include <HardwareTimer.h>
2121 # if defined(SEND_PWM_BY_TIMER)
2122 #error PWM generation by hardware not implemented for STM32
2129 HardwareTimer s50usTimer(3);
2132 s50usTimer.resume();
2144 s50usTimer.setMode(TIMER_CH1, TIMER_OUTPUT_COMPARE);
2145 s50usTimer.setPrescaleFactor(1);
2148 s50usTimer.refresh();
2157 #elif defined(STM32F1xx) || defined(ARDUINO_ARCH_STM32)
2158 #include <HardwareTimer.h>
2159 # if defined(SEND_PWM_BY_TIMER)
2160 #error PWM generation by hardware not implemented for STM32
2168 HardwareTimer s50usTimer(TIM4);
2170 HardwareTimer s50usTimer(TIM2);
2174 s50usTimer.resume();
2188 s50usTimer.resume();
2195 #elif defined(PARTICLE)
2196 # ifndef __INTERVALTIMER_H__
2197 #include "SparkIntervalTimer.h"
2200 extern IntervalTimer timer;
2201 extern int ir_out_kHz;
2218 # if defined(SEND_PWM_BY_TIMER)
2219 # if defined(IR_SEND_PIN)
2242 # if defined(IR_SEND_PIN)
2247 ir_out_kHz = aFrequencyKHz;
2249 # endif // defined(SEND_PWM_BY_TIMER)
2255 #error Internal code configuration error, no timer functions implemented for this CPU / board
2266 #define ISR() void notImplemented(void)
2271 # if defined(SEND_PWM_BY_TIMER)
2279 # if defined(IR_SEND_PIN)
2284 (void) aFrequencyKHz;
2286 # endif // defined(SEND_PWM_BY_TIMER)
2288 #endif // defined(DOXYGEN / CPU_TYPES)
2292 #endif // _IR_TIMER_HPP