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.
143 #elif defined(__AVR__)
152 #if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328PB__) || defined(__AVR_ATmega168__) \
153 || defined(__AVR_ATmega88P__) || defined(__AVR_ATmega88PB__)
154 # if !defined(IR_USE_AVR_TIMER1) && !defined(IR_USE_AVR_TIMER2)
156 #define IR_USE_AVR_TIMER2 // send pin = pin 3
160 #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
161 # 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)
163 #define IR_USE_AVR_TIMER2 // send pin = pin 9
170 #elif defined(__AVR_ATmega32U4__) && ! defined(TEENSYDUINO) && ! defined(ARDUINO_AVR_PROMICRO)
171 # if !defined(IR_USE_AVR_TIMER1) && !defined(IR_USE_AVR_TIMER3) && !defined(IR_USE_AVR_TIMER4_HS)
173 #define IR_USE_AVR_TIMER3 // send pin = pin 5
178 #elif defined(__AVR_ATmega808__) || defined(__AVR_ATmega809__) || defined(__AVR_ATmega3208__) || defined(__AVR_ATmega3209__) \
179 || defined(__AVR_ATmega1608__) || defined(__AVR_ATmega1609__) || defined(__AVR_ATmega4808__) || defined(__AVR_ATmega4809__) || defined(__AVR_ATtiny1604__)
180 # if !defined(IR_USE_AVR_TIMER_B)
181 #define IR_USE_AVR_TIMER_B // send pin = pin 6 on ATmega4809 1 on ATmega4809
184 #elif defined(__AVR_ATtiny816__) || defined(__AVR_ATtiny1614__) || defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__) // e.g. TinyCore boards
185 # if !defined(IR_USE_AVR_TIMER_A) && !defined(IR_USE_AVR_TIMER_D)
186 #define IR_USE_AVR_TIMER_A // use this if you use megaTinyCore, Tone is on TCB and millis() on TCD
191 #elif defined(__AVR_ATmega8U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega8__)
192 # if !defined(IR_USE_AVR_TIMER1)
193 #define IR_USE_AVR_TIMER1 // send pin = pin C6
197 #elif defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny88__)
198 # if !defined(IR_USE_AVR_TIMER1)
199 #define IR_USE_AVR_TIMER1 // send pin = pin 6, no tone() available when using ATTinyCore
202 #elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)
203 # if !defined(IR_USE_AVR_TIMER1)
204 #define IR_USE_AVR_TIMER1 // send pin = pin PB1 / 8
206 #define USE_TIMER_CHANNEL_B
209 #elif defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
210 # if !defined(IR_USE_AVR_TIMER_TINY0) && !defined(IR_USE_AVR_TIMER_TINY1)
211 # if defined(ARDUINO_AVR_DIGISPARK) // tested with 16 and 8 MHz
212 #define IR_USE_AVR_TIMER_TINY0 // send pin = pin 1
216 #define IR_USE_AVR_TIMER_TINY1 // send pin = pin 4
223 #elif defined(ARDUINO_AVR_PROMICRO)
224 # if !defined(IR_USE_AVR_TIMER1) && !defined(IR_USE_AVR_TIMER3) && !defined(IR_USE_AVR_TIMER4_HS)
226 #define IR_USE_AVR_TIMER3 // send pin = pin 5
234 #elif defined(__AVR_AT90USB162__)
235 # if !defined(IR_USE_AVR_TIMER1)
236 #define IR_USE_AVR_TIMER1 // send pin = pin 17
240 #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
241 # if !defined(IR_USE_AVR_TIMER1) && !defined(IR_USE_AVR_TIMER2) && !defined(IR_USE_AVR_TIMER3)
243 #define IR_USE_AVR_TIMER2 // send pin = pin 1
248 #elif defined(__AVR_ATmega32U4__) && defined(TEENSYDUINO)
249 # if !defined(IR_USE_AVR_TIMER1) && !defined(IR_USE_AVR_TIMER3) && !defined(IR_USE_AVR_TIMER4_HS)
252 #define IR_USE_AVR_TIMER4_HS // send pin = pin 10 (Teensy 2.0 - physical pin: C7)
259 #elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2560__)
260 # if !defined(IR_USE_AVR_TIMER1)
261 #define IR_USE_AVR_TIMER1 // send pin = pin 13
267 #elif defined(__AVR_ATmega8515__) || defined(__AVR_ATmega162__)
268 # if !defined(IR_USE_AVR_TIMER1) && !defined(IR_USE_AVR_TIMER3)
269 #define IR_USE_AVR_TIMER1 // send pin = pin 13
277 #elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)
278 # if !defined(IR_USE_AVR_TIMER1) && !defined(IR_USE_AVR_TIMER2) && !defined(IR_USE_AVR_TIMER3)
280 #define IR_USE_AVR_TIMER2 // send pin = pin 14
285 #elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \
286 || defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \
287 || defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \
288 || defined(__AVR_ATmega164P__)
289 # if !defined(IR_USE_AVR_TIMER1) && !defined(IR_USE_AVR_TIMER2)
291 #define IR_USE_AVR_TIMER2 // send pin = pin 14
295 #elif defined(__AVR_ATmega8535__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__)
296 # if !defined(IR_USE_AVR_TIMER1)
297 #define IR_USE_AVR_TIMER1 // send pin = pin 13
307 #if defined(IR_USE_AVR_TIMER1)
310 #define TIMSK TIMSK1 // use the value of TIMSK1 for the statements below
314 TIMSK |= _BV(OCIE1A);
317 TIMSK &= ~_BV(OCIE1A);
320 # if defined(USE_TIMER_CHANNEL_B)
321 # if defined(TIMER1_COMPB_vect)
322 #define TIMER_INTR_NAME TIMER1_COMPB_vect
323 # elif defined(TIM1_COMPB_vect)
324 #define TIMER_INTR_NAME TIM1_COMPB_vect
327 # if defined(TIMER1_COMPA_vect)
328 #define TIMER_INTR_NAME TIMER1_COMPA_vect
329 # elif defined(TIM1_COMPA_vect)
330 #define TIMER_INTR_NAME TIM1_COMPA_vect
336 TCCR1B = _BV(WGM12) | _BV(CS10);
341 # if defined(SEND_PWM_BY_TIMER)
342 # if defined(CORE_OC1A_PIN)
343 #define IR_SEND_PIN CORE_OC1A_PIN // Teensy
345 # elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
346 #define IR_SEND_PIN 11 // Arduino Mega
349 # elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \
350 || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \
351 || defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \
352 || defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \
353 || defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \
354 || defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__) \
355 || defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) \
356 || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) \
357 || defined(__AVR_ATmega8515__) || defined(__AVR_ATmega162__)
358 #define IR_SEND_PIN 13
360 # elif defined(__AVR_ATtiny84__)
361 #define IR_SEND_PIN 6
363 # elif defined(__AVR_ATtiny88__)
364 #define IR_SEND_PIN 8
366 # elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)
370 # if defined(USE_TIMER_CHANNEL_B)
371 #define IR_SEND_PIN PIN_PB1 // OC1BU / PB1 / Pin9 at ATTinyCore
376 #define IR_SEND_PIN PIN_PB0 // OC1AU / PB1 / Pin8 at ATTinyCore
383 #define IR_SEND_PIN 9 // OC1A Arduino Duemilanove, Diecimila, LilyPad, Sparkfun Pro Micro, Leonardo, MH-ET Tiny88 etc.
384 # endif // defined(CORE_OC1A_PIN)
386 # if defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)
388 # if defined(USE_TIMER_CHANNEL_B)
391 TCCR1A |= _BV(COM1B1);
392 TCCR1D |= _BV(OC1BU);
400 TCCR1A |= _BV(COM1A1);
401 TCCR1D |= _BV(OC1AU);
412 # if defined(USE_TIMER_CHANNEL_B)
415 TCCR1A |= _BV(COM1B1);
418 TCCR1A &= ~(_BV(COM1B1));
423 TCCR1A |= _BV(COM1A1);
426 TCCR1A &= ~(_BV(COM1A1));
438 # if (((F_CPU / 2000) / 38) < 256)
439 const uint16_t tPWMWrapValue = (F_CPU / 2000) / (aFrequencyKHz);
441 TCCR1B = _BV(WGM13) | _BV(CS10);
442 ICR1 = tPWMWrapValue - 1;
443 # if defined(USE_TIMER_CHANNEL_B)
450 const uint16_t tPWMWrapValue = ((F_CPU / 8) / 2000) / (aFrequencyKHz);
452 TCCR1B = _BV(WGM13) | _BV(CS11);
453 ICR1 = tPWMWrapValue - 1;
454 # if defined(USE_TIMER_CHANNEL_B)
462 # endif // defined(SEND_PWM_BY_TIMER)
467 #elif defined(IR_USE_AVR_TIMER2)
470 TIMSK2 = _BV(OCIE2B);
475 #define TIMER_INTR_NAME TIMER2_COMPB_vect // We use TIMER2_COMPB_vect to be compatible with tone() library
477 #define TIMER_COUNT_TOP (F_CPU * MICROS_PER_TICK / MICROS_IN_ONE_SECOND)
480 # if (TIMER_COUNT_TOP < 256)
483 OCR2A = TIMER_COUNT_TOP;
484 OCR2B = TIMER_COUNT_TOP;
489 OCR2A = TIMER_COUNT_TOP / 8;
490 OCR2B = TIMER_COUNT_TOP / 8;
495 # if defined(SEND_PWM_BY_TIMER)
496 # if defined(CORE_OC2B_PIN)
497 #define IR_SEND_PIN CORE_OC2B_PIN // Teensy
499 # elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
500 #define IR_SEND_PIN 9 // Arduino Mega
502 # elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \
503 || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \
504 || defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \
505 || defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \
506 || defined(__AVR_ATmega164P__)
507 #define IR_SEND_PIN 14 // MightyCore, MegaCore
510 #define IR_SEND_PIN 3 // Arduino Duemilanove, Diecimila, LilyPad, etc
511 # endif // defined(CORE_OC2B_PIN)
515 TCCR2A |= _BV(COM2B1);
518 TCCR2A &= ~(_BV(COM2B1));
528 # if (((F_CPU / 2000) / 38) < 256)
534 const uint16_t tPWMWrapValue = (F_CPU / 2000) / (aFrequencyKHz);
536 TCCR2B = _BV(WGM22) | _BV(CS20);
537 OCR2A = tPWMWrapValue - 1;
541 const uint16_t tPWMWrapValue = ((F_CPU / 8) / 2000) / (aFrequencyKHz);
543 TCCR2B = _BV(WGM22) | _BV(CS21);
544 OCR2A = tPWMWrapValue - 1;
549 # endif // defined(SEND_PWM_BY_TIMER)
554 #elif defined(IR_USE_AVR_TIMER3)
557 TIMSK3 = _BV(OCIE3B);
562 #define TIMER_INTR_NAME TIMER3_COMPB_vect
566 TCCR3B = _BV(WGM32) | _BV(CS30);
572 # if defined(SEND_PWM_BY_TIMER)
573 # if defined(CORE_OC3A_PIN)
574 #define IR_SEND_PIN CORE_OC3A_PIN // Teensy
576 # elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) \
577 || defined(__AVR_ATmega32U4__) || defined(ARDUINO_AVR_PROMICRO)
578 #define IR_SEND_PIN 5 // Arduino Mega, Arduino Leonardo, Sparkfun Pro Micro
580 # elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)
581 #define IR_SEND_PIN 6 // MightyCore, MegaCore
584 #error Please add OC3A pin number here
589 TCCR3A |= _BV(COM3A1);
592 TCCR3A &= ~(_BV(COM3A1));
601 #error "Creating timer PWM with timer 3 is not supported for F_CPU > 16 MHz"
605 const uint16_t tPWMWrapValue = (F_CPU / 2000) / (aFrequencyKHz);
607 TCCR3B = _BV(WGM33) | _BV(CS30);
608 ICR3 = tPWMWrapValue - 1;
612 # endif // defined(SEND_PWM_BY_TIMER)
617 #elif defined(IR_USE_AVR_TIMER4)
619 TIMSK4 = _BV(OCIE4A);
624 #define TIMER_INTR_NAME TIMER4_COMPA_vect
628 TCCR4B = _BV(WGM42) | _BV(CS40);
633 # if defined(SEND_PWM_BY_TIMER)
634 # if defined(CORE_OC4A_PIN)
635 #define IR_SEND_PIN CORE_OC4A_PIN
636 # elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
637 #define IR_SEND_PIN 6 // Arduino Mega
639 #error Please add OC4A pin number here
644 TCCR4A |= _BV(COM4A1);
647 TCCR4A &= ~(_BV(COM4A1));
652 #error "Creating timer PWM with timer 4 is not supported for F_CPU > 16 MHz"
655 const uint16_t tPWMWrapValue = (F_CPU / 2000) / (aFrequencyKHz);
657 TCCR4B = _BV(WGM43) | _BV(CS40);
658 ICR4 = tPWMWrapValue - 1;
662 # endif // defined(SEND_PWM_BY_TIMER)
667 #elif defined(IR_USE_AVR_TIMER4_HS)
675 #define TIMER_INTR_NAME TIMER4_OVF_vect
689 # if defined(SEND_PWM_BY_TIMER)
690 # if defined(CORE_OC4A_PIN)
691 #define IR_SEND_PIN CORE_OC4A_PIN // Teensy 2.0
692 # elif defined(ARDUINO_AVR_PROMICRO)
693 #define IR_SEND_PIN 5 // Sparkfun Pro Micro
694 # elif defined(__AVR_ATmega32U4__)
695 #define IR_SEND_PIN 13 // Leonardo
697 #error Please add OC4A pin number here
700 # if defined(ARDUINO_AVR_PROMICRO) // Sparkfun Pro Micro
703 TCCR4A |= _BV(COM4A0);
706 TCCR4A &= ~(_BV(COM4A0));
712 TCCR4A |= _BV(COM4A1);
716 TCCR4A &= ~(_BV(COM4A1));
726 #error "Creating timer PWM with timer 4 HS is not supported for F_CPU > 16 MHz"
730 const uint16_t tPWMWrapValue = ((F_CPU / 2000) / (aFrequencyKHz)) - 1;
731 TCCR4A = (1 << PWM4A);
734 TCCR4D = (1 << WGM40);
736 TC4H = tPWMWrapValue >> 8;
737 OCR4C = tPWMWrapValue;
742 # endif // defined(SEND_PWM_BY_TIMER)
747 #elif defined(IR_USE_AVR_TIMER5)
750 TIMSK5 = _BV(OCIE5A);
755 #define TIMER_INTR_NAME TIMER5_COMPA_vect
759 TCCR5B = _BV(WGM52) | _BV(CS50);
764 # if defined(SEND_PWM_BY_TIMER)
765 # if defined(CORE_OC5A_PIN)
766 #define IR_SEND_PIN CORE_OC5A_PIN
767 # elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
768 #define IR_SEND_PIN 46 // Arduino Mega
770 #error Please add OC5A pin number here
775 TCCR5A |= _BV(COM5A1);
778 TCCR5A &= ~(_BV(COM5A1));
787 #error "Creating timer PWM with timer 5 is not supported for F_CPU > 16 MHz"
791 const uint16_t tPWMWrapValue = (F_CPU / 2000) / (aFrequencyKHz);
793 TCCR5B = _BV(WGM53) | _BV(CS50);
794 ICR5 = tPWMWrapValue - 1;
798 # endif // defined(SEND_PWM_BY_TIMER)
803 #elif defined(IR_USE_AVR_TIMER_TINY0)
806 TIMSK |= _BV(OCIE0A);
809 TIMSK &= ~(_BV(OCIE0A));
811 #define TIMER_INTR_NAME TIMER0_COMPA_vect
813 #define TIMER_COUNT_TOP (F_CPU * MICROS_PER_TICK / MICROS_IN_ONE_SECOND)
816 # if (TIMER_COUNT_TOP < 256)
819 OCR0A = TIMER_COUNT_TOP;
824 OCR0A = TIMER_COUNT_TOP / 8;
829 # if defined(SEND_PWM_BY_TIMER)
830 #define IR_SEND_PIN 1
834 TCCR0A |= _BV(COM0B1);
837 TCCR0A &= ~(_BV(COM0B1));
846 #error "Creating timer PWM with timer TINY0 is not supported for F_CPU > 16 MHz"
850 const uint16_t tPWMWrapValue = (F_CPU / 2000) / (aFrequencyKHz);
852 TCCR0B = _BV(WGM02) | _BV(CS00);
853 OCR0A = tPWMWrapValue - 1;
857 # endif // defined(SEND_PWM_BY_TIMER)
862 #elif defined(IR_USE_AVR_TIMER_TINY1)
865 TIMSK |= _BV(OCIE1B);
868 TIMSK &= ~(_BV(OCIE1B));
870 #define TIMER_INTR_NAME TIMER1_COMPB_vect
872 #define TIMER_COUNT_TOP (F_CPU * MICROS_PER_TICK / MICROS_IN_ONE_SECOND)
875 # if (TIMER_COUNT_TOP < 256)
876 TCCR1 = _BV(CTC1) | _BV(CS10);
878 OCR1C = TIMER_COUNT_TOP;
881 TCCR1 = _BV(CTC1) | _BV(CS12);
883 OCR1C = TIMER_COUNT_TOP / 8;
888 # if defined(SEND_PWM_BY_TIMER)
889 #define IR_SEND_PIN 4
893 GTCCR |= _BV(PWM1B) | _BV(COM1B0);
896 GTCCR &= ~(_BV(PWM1B) | _BV(COM1B0));
906 # if (((F_CPU / 1000) / 38) < 256)
907 const uint16_t tPWMWrapValue = (F_CPU / 1000) / (aFrequencyKHz);
908 TCCR1 = _BV(CTC1) | _BV(CS10);
909 OCR1C = tPWMWrapValue - 1;
912 GTCCR = _BV(PWM1B) | _BV(COM1B0);
914 const uint16_t tPWMWrapValue = ((F_CPU / 2) / 1000) / (aFrequencyKHz);
915 TCCR1 = _BV(CTC1) | _BV(CS11);
916 OCR1C = tPWMWrapValue - 1;
919 GTCCR = _BV(PWM1B) | _BV(COM1B0);
922 # endif // defined(SEND_PWM_BY_TIMER)
927 #elif defined(IR_USE_AVR_TIMER_A)
928 #define TIMER_REQUIRES_RESET_INTR_PENDING
930 TCA0.SINGLE.INTFLAGS = TCA_SINGLE_OVF_bm;
933 TCA0.SINGLE.INTCTRL = TCA_SINGLE_OVF_bm;
936 TCA0.SINGLE.INTCTRL &= ~(TCA_SINGLE_OVF_bm);
938 #define TIMER_INTR_NAME TCA0_OVF_vect
945 TCA0.SINGLE.CTRLD = 0;
946 TCA0.SINGLE.CTRLB = TCA_SINGLE_WGMODE_NORMAL_gc;
948 TCA0.SINGLE.CTRLA = TCA_SINGLE_CLKSEL_DIV1_gc | TCA_SINGLE_ENABLE_bm;
951 # if defined(SEND_PWM_BY_TIMER)
952 #error "No support for hardware PWM generation for ATtiny3216/17 etc."
953 # endif // defined(SEND_PWM_BY_TIMER)
958 #elif defined(IR_USE_AVR_TIMER_B)
961 #define TIMER_REQUIRES_RESET_INTR_PENDING
963 TCB0.INTFLAGS = TCB_CAPT_bm;
966 TCB0.INTCTRL = TCB_CAPT_bm;
969 TCB0.INTCTRL &= ~(TCB_CAPT_bm);
971 #define TIMER_INTR_NAME TCB0_INT_vect
974 TCB0.CTRLB = (TCB_CNTMODE_INT_gc);
976 TCB0.INTFLAGS = TCB_CAPT_bm;
977 TCB0.CTRLA = (TCB_CLKSEL_CLKDIV1_gc) | (TCB_ENABLE_bm);
980 # if defined(SEND_PWM_BY_TIMER)
981 # if defined(__AVR_ATmega4808__) || defined(__AVR_ATmega4809__)
982 #define IR_SEND_PIN 6 // PF4 on ATmega4809 / Nano Every (see pins_arduino.h digital_pin_to_timer)
984 #error SEND_PWM_BY_TIMER not yet supported for this CPU
989 TCB0.CTRLB |= TCB_CCMPEN_bm;
992 TCB0.CTRLB &= ~(TCB_CCMPEN_bm);
1000 #if F_CPU > 16000000
1002 #error "Creating timer PWM with timer TCB0 is not possible for F_CPU > 16 MHz"
1006 const uint16_t tPWMWrapValue = (F_CPU / 2000) / (aFrequencyKHz);
1007 TCB0.CTRLB = TCB_CNTMODE_PWM8_gc;
1008 TCB0.CCMPL = tPWMWrapValue - 1;
1010 TCB0.CTRLA = (TCB_CLKSEL_CLKDIV2_gc) | (TCB_ENABLE_bm);
1013 # endif // defined(SEND_PWM_BY_TIMER)
1018 #elif defined(IR_USE_AVR_TIMER_D)
1020 #define TIMER_REQUIRES_RESET_INTR_PENDING
1022 TCD0.INTFLAGS = TCD_OVF_bm;
1025 TCD0.INTCTRL = TCD_OVF_bm;
1030 #define TIMER_INTR_NAME TCD0_OVF_vect
1034 TCD0.CTRLB = TCD_WGMODE_ONERAMP_gc;
1038 _PROTECTED_WRITE(TCD0.FAULTCTRL, 0);
1040 TCD0.INTFLAGS = TCD_OVF_bm;
1044 TCD0.CTRLA = TCD_ENABLE_bm | TCD_CLKSEL_SYSCLK_gc | TCD_CNTPRES_DIV1_gc;
1047 # if defined(SEND_PWM_BY_TIMER)
1048 #define IR_SEND_PIN 13
1050 void timerEnableSendPWM() {
1052 _PROTECTED_WRITE(TCD0.FAULTCTRL, FUSE_CMPAEN_bm);
1054 TCD0.CTRLA = TCD_ENABLE_bm | TCD_CLKSEL_SYSCLK_gc | TCD_CNTPRES_DIV1_gc;
1058 timerEnableSendPWM();
1071 const uint16_t tPWMWrapValue = (F_CPU / 1000) / (aFrequencyKHz);
1075 TCD0.CTRLB = TCD_WGMODE_ONERAMP_gc;
1078 TCD0.CMPBCLR = tPWMWrapValue - 1;
1084 TCD0.INTFLAGS = TCD_OVF_bm;
1085 TCD0.INTCTRL = TCD_OVF_bm;
1088 # endif // defined(SEND_PWM_BY_TIMER)
1091 #error Internal code configuration error, no timer functions implemented for this AVR CPU / board
1092 #endif //defined(IR_USE_AVR_TIMER*)
1100 #elif defined(ARDUINO_ARCH_RENESAS)
1101 #include "FspTimer.h"
1102 FspTimer s50usTimer;
1110 void IRTimerInterruptHandlerHelper(timer_callback_args_t __attribute((unused)) *p_args) {
1123 uint8_t tTimerType = GPT_TIMER;
1124 int8_t tIndex = FspTimer::get_available_timer(tTimerType);
1125 if (tIndex < 0 || tTimerType != GPT_TIMER) {
1127 tIndex = FspTimer::get_available_timer(tTimerType,
true);
1134 IRTimerInterruptHandlerHelper);
1135 s50usTimer.setup_overflow_irq();
1140 # if defined(SEND_PWM_BY_TIMER)
1141 #error PWM generation by hardware not yet implemented for Arduino Uno R4
1152 # if defined(IR_SEND_PIN)
1161 #elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
1164 #define TIMER_REQUIRES_RESET_INTR_PENDING
1166 uint8_t tmp __attribute__((unused)) = CMT_MSC;
1170 NVIC_ENABLE_IRQ(IRQ_CMT);
1171 NVIC_SET_PRIORITY(IRQ_CMT, 48);
1174 NVIC_DISABLE_IRQ(IRQ_CMT);
1177 #define TIMER_INTR_NAME cmt_isr
1181 #define ISR(f) void f(void)
1183 #define CMT_PPS_DIV ((F_BUS + 7999999) / 8000000)
1184 # if F_BUS < 8000000
1185 #error IRremote requires at least 8 MHz on Teensy 3.x
1189 SIM_SCGC4 |= SIM_SCGC4_CMT;
1190 CMT_PPS = CMT_PPS_DIV - 1;
1196 CMT_CMD4 = (F_BUS / 160000 + CMT_PPS_DIV / 2) / CMT_PPS_DIV - 31;
1201 # if defined(SEND_PWM_BY_TIMER)
1202 #define IR_SEND_PIN 5
1206 CORE_PIN5_CONFIG = PORT_PCR_MUX(2) | PORT_PCR_DSE | PORT_PCR_SRE;
1211 CORE_PIN5_CONFIG = PORT_PCR_MUX(1) | PORT_PCR_DSE | PORT_PCR_SRE;
1221 # if defined(IR_SEND_PIN)
1227 SIM_SCGC4 |= SIM_SCGC4_CMT;
1228 SIM_SOPT2 |= SIM_SOPT2_PTD7PAD;
1229 CMT_PPS = CMT_PPS_DIV - 1;
1230 CMT_CGH1 = ((F_BUS / CMT_PPS_DIV / 3000) + ((aFrequencyKHz) / 2)) / (aFrequencyKHz);
1231 CMT_CGL1 = ((F_BUS / CMT_PPS_DIV / 1500) + ((aFrequencyKHz) / 2)) / (aFrequencyKHz);
1239 # endif // defined(SEND_PWM_BY_TIMER)
1244 #elif defined(__MKL26Z64__)
1247 #define TIMER_REQUIRES_RESET_INTR_PENDING
1249 FTM1_SC |= FTM_SC_TOF;
1252 NVIC_ENABLE_IRQ(IRQ_FTM1);
1253 NVIC_SET_PRIORITY(IRQ_FTM1, 0);
1256 NVIC_DISABLE_IRQ(IRQ_FTM1);
1258 #define TIMER_INTR_NAME ftm1_isr
1262 #define ISR(f) void f(void)
1265 SIM_SCGC6 |= SIM_SCGC6_TPM1;
1268 FTM1_MOD = (F_PLL / 40000) - 1;
1270 FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0) | FTM_SC_TOF | FTM_SC_TOIE;
1273 # if defined(SEND_PWM_BY_TIMER)
1274 #define IR_SEND_PIN 16
1278 CORE_PIN16_CONFIG = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
1281 CORE_PIN16_CONFIG = PORT_PCR_MUX(1) | PORT_PCR_SRE;
1290 # if defined(IR_SEND_PIN)
1296 SIM_SCGC6 |= SIM_SCGC6_TPM1;
1299 FTM1_MOD = ((F_PLL / 2000) / aFrequencyKHz) - 1;
1300 FTM1_C0V = ((F_PLL / 6000) / aFrequencyKHz) - 1;
1301 FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0);
1303 # endif // defined(SEND_PWM_BY_TIMER)
1308 #elif defined(__IMXRT1062__)
1313 #define TIMER_REQUIRES_RESET_INTR_PENDING
1315 FLEXPWM1_SM3STS = FLEXPWM_SMSTS_RF;
1318 attachInterruptVector(IRQ_FLEXPWM1_3, pwm1_3_isr);
1319 FLEXPWM1_SM3STS = FLEXPWM_SMSTS_RF;
1320 FLEXPWM1_SM3INTEN = FLEXPWM_SMINTEN_RIE;
1321 NVIC_ENABLE_IRQ (IRQ_FLEXPWM1_3), NVIC_SET_PRIORITY(IRQ_FLEXPWM1_3, 48);
1324 NVIC_DISABLE_IRQ (IRQ_FLEXPWM1_3);
1326 #define TIMER_INTR_NAME pwm1_3_isr
1330 #define ISR(f) void (f)(void)
1333 uint32_t period = (float) F_BUS_ACTUAL * (
float) (
MICROS_PER_TICK) * 0.0000005f;
1334 uint32_t prescale = 0;
1335 while (period > 32767) {
1336 period = period >> 1;
1340 FLEXPWM1_FCTRL0 |= FLEXPWM_FCTRL0_FLVL(8);
1341 FLEXPWM1_FSTS0 = 0x0008;
1342 FLEXPWM1_MCTRL |= FLEXPWM_MCTRL_CLDOK(8);
1343 FLEXPWM1_SM3CTRL2 = FLEXPWM_SMCTRL2_INDEP;
1344 FLEXPWM1_SM3CTRL = FLEXPWM_SMCTRL_HALF | FLEXPWM_SMCTRL_PRSC(prescale);
1345 FLEXPWM1_SM3INIT = -period;
1346 FLEXPWM1_SM3VAL0 = 0;
1347 FLEXPWM1_SM3VAL1 = period;
1348 FLEXPWM1_SM3VAL2 = 0;
1349 FLEXPWM1_SM3VAL3 = 0;
1350 FLEXPWM1_SM3VAL4 = 0;
1351 FLEXPWM1_SM3VAL5 = 0;
1352 FLEXPWM1_MCTRL |= FLEXPWM_MCTRL_LDOK(8) | FLEXPWM_MCTRL_RUN(8);
1355 # if defined(SEND_PWM_BY_TIMER)
1356 #define IR_SEND_PIN 7
1358 FLEXPWM1_OUTEN |= FLEXPWM_OUTEN_PWMA_EN(8);
1359 IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_00 = 6;
1363 IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_00 = 5;
1364 FLEXPWM1_OUTEN &= ~FLEXPWM_OUTEN_PWMA_EN(8);
1373 # if defined(IR_SEND_PIN)
1379 uint32_t period = (float) F_BUS_ACTUAL / (
float) ((aFrequencyKHz) * 2000);
1380 uint32_t prescale = 0;
1381 while (period > 32767) {
1382 period = period >> 1;
1386 FLEXPWM1_FCTRL0 |= FLEXPWM_FCTRL0_FLVL(8);
1387 FLEXPWM1_FSTS0 = 0x0008;
1388 FLEXPWM1_MCTRL |= FLEXPWM_MCTRL_CLDOK(8);
1389 FLEXPWM1_SM3CTRL2 = FLEXPWM_SMCTRL2_INDEP;
1390 FLEXPWM1_SM3CTRL = FLEXPWM_SMCTRL_HALF | FLEXPWM_SMCTRL_PRSC(prescale);
1391 FLEXPWM1_SM3INIT = -period;
1392 FLEXPWM1_SM3VAL0 = 0;
1393 FLEXPWM1_SM3VAL1 = period;
1394 FLEXPWM1_SM3VAL2 = -(period / 3);
1395 FLEXPWM1_SM3VAL3 = period / 3;
1396 FLEXPWM1_SM3VAL4 = 0;
1397 FLEXPWM1_SM3VAL5 = 0;
1398 FLEXPWM1_MCTRL |= FLEXPWM_MCTRL_LDOK(8) | FLEXPWM_MCTRL_RUN(8);
1400 # endif // defined(SEND_PWM_BY_TIMER)
1405 #elif defined(ESP8266)
1406 # if defined(SEND_PWM_BY_TIMER)
1407 #error "No support for hardware PWM generation for ESP8266"
1408 # endif // defined(SEND_PWM_BY_TIMER)
1419 timer1_detachInterrupt();
1429 timer1_enable(TIM_DIV16, TIM_EDGE, TIM_LOOP);
1438 #elif defined(ESP32)
1439 # if !defined(ESP_ARDUINO_VERSION)
1440 #define ESP_ARDUINO_VERSION 0x010101 // Version 1.1.1
1442 # if !defined(ESP_ARDUINO_VERSION_VAL)
1443 #define ESP_ARDUINO_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch))
1448 hw_timer_t *s50usTimer =
nullptr;
1450 # if ESP_ARDUINO_VERSION < ESP_ARDUINO_VERSION_VAL(3, 0, 0) && !defined(SEND_LEDC_CHANNEL)
1451 #define SEND_LEDC_CHANNEL 0 // The channel used for PWM 0 to 7 are high speed PWM channels
1455 # if ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 0)
1456 timerStart(s50usTimer);
1458 timerAlarmEnable(s50usTimer);
1462 # if ESP_ARDUINO_VERSION < ESP_ARDUINO_VERSION_VAL(2, 0, 2)
1467 if (s50usTimer !=
nullptr) {
1468 timerDetachInterrupt(s50usTimer);
1469 timerEnd(s50usTimer);
1475 if (s50usTimer !=
nullptr) {
1476 # if ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 0)
1477 timerStop(s50usTimer);
1479 timerAlarmDisable(s50usTimer);
1490 # if !defined(DISABLE_CODE_FOR_RECEIVER) // Otherwise the &IRReceiveTimerInterruptHandler is referenced, but not available
1495 if(s50usTimer ==
nullptr) {
1496 # if ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 0)
1497 s50usTimer = timerBegin(1000000);
1498 timerStop(s50usTimer);
1502 s50usTimer = timerBegin(1, 80,
true);
1512 uint8_t sLastSendPin = 0;
1514 # if defined(SEND_PWM_BY_TIMER)
1516 # if ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 0)
1517 # if defined(IR_SEND_PIN)
1528 # if ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 0)
1529 # if defined(IR_SEND_PIN)
1536 ledcWrite(SEND_LEDC_CHANNEL, 0);
1545 # if ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 0)
1546 # if defined(IR_SEND_PIN)
1547 if(sLastSendPin == 0){
1560 ledcSetup(SEND_LEDC_CHANNEL, aFrequencyKHz * 1000, 8);
1561 # if defined(IR_SEND_PIN)
1572 # endif // defined(SEND_PWM_BY_TIMER)
1577 #elif defined(ARDUINO_ARCH_SAMD)
1578 # if defined(SEND_PWM_BY_TIMER)
1579 #error PWM generation by hardware is not yet implemented for SAMD
1582 # if !defined(IR_SAMD_TIMER)
1583 # if defined(__SAMD51__)
1585 #define IR_SAMD_TIMER TC5
1586 #define IR_SAMD_TIMER_IRQ TC5_IRQn
1588 #define IR_SAMD_TIMER TC3
1589 #define IR_SAMD_TIMER_IRQ TC3_IRQn
1593 #define IR_SAMD_TIMER TC3
1594 #define IR_SAMD_TIMER_ID GCLK_CLKCTRL_ID_TCC2_TC3
1595 #define IR_SAMD_TIMER_IRQ TC3_IRQn
1600 NVIC_EnableIRQ (IR_SAMD_TIMER_IRQ);
1603 NVIC_DisableIRQ (IR_SAMD_TIMER_IRQ);
1621 TcCount16 *TC = (TcCount16*) IR_SAMD_TIMER;
1623 # if defined(__SAMD51__)
1625 # if defined(TC5_GCLK_ID)
1626 GCLK->PCHCTRL[TC5_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK0_Val | (1 << GCLK_PCHCTRL_CHEN_Pos);
1628 GCLK->PCHCTRL[TC3_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK0_Val | (1 << GCLK_PCHCTRL_CHEN_Pos);
1632 TC->CTRLA.reg &= ~TC_CTRLA_ENABLE;
1633 while (TC->SYNCBUSY.bit.ENABLE)
1636 TC->CTRLA.reg = TC_CTRLA_SWRST;
1638 while (TC->SYNCBUSY.bit.SWRST)
1647 TC->CTRLA.reg |= TC_CTRLA_MODE_COUNT16 | TC_WAVE_WAVEGEN_MFRQ | TC_CTRLA_PRESCALER_DIV16 | TC_CTRLA_ENABLE;
1651 REG_GCLK_CLKCTRL = (uint16_t)(GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | IR_SAMD_TIMER_ID);
1652 while (GCLK->STATUS.bit.SYNCBUSY == 1)
1656 TC->CTRLA.reg &= ~TC_CTRLA_ENABLE;
1658 while (TC->STATUS.bit.SYNCBUSY == 1)
1661 TC->CTRLA.reg = TC_CTRLA_SWRST;
1663 while (TC->CTRLA.bit.SWRST)
1672 TC->CTRLA.reg |= TC_CTRLA_MODE_COUNT16 | TC_CTRLA_WAVEGEN_MFRQ | TC_CTRLA_PRESCALER_DIV16 | TC_CTRLA_ENABLE;
1676 NVIC_DisableIRQ (IR_SAMD_TIMER_IRQ);
1677 NVIC_ClearPendingIRQ(IR_SAMD_TIMER_IRQ);
1678 NVIC_SetPriority(IR_SAMD_TIMER_IRQ, 0);
1679 NVIC_EnableIRQ(IR_SAMD_TIMER_IRQ);
1682 TC->INTENSET.bit.MC0 = 1;
1685 # if !defined(DISABLE_CODE_FOR_RECEIVER)
1686 # if defined(__SAMD51__) && defined(TC5)
1687 void TC5_Handler(
void)
1689 void TC3_Handler(
void)
1690 # endif // defined(__SAMD51__)
1692 TcCount16 *TC = (TcCount16*) IR_SAMD_TIMER;
1694 if (TC->INTFLAG.bit.MC0 == 1) {
1696 TC->INTFLAG.bit.MC0 = 1;
1700 # endif // !defined(DISABLE_CODE_FOR_RECEIVER)
1705 #elif defined(ARDUINO_ARCH_MBED) // Arduino Nano 33 BLE + Sparkfun Apollo3 + Nano RP2040 Connect
1707 mbed::Ticker s50usTimer;
1718 s50usTimer.detach();
1725 # if defined(SEND_PWM_BY_TIMER)
1726 #include "pins_arduino.h"
1728 # if defined(IR_SEND_PIN)
1729 mbed::PwmOut sPwmOutForSendPWM(digitalPinToPinName(
IR_SEND_PIN));
1731 mbed::PwmOut sPwmOutForSendPWM(digitalPinToPinName(
IrSender.
sendPin));
1733 uint8_t sIROutPuseWidth;
1736 sPwmOutForSendPWM.pulsewidth_us(sIROutPuseWidth);
1742 sPwmOutForSendPWM.pulsewidth_us(0);
1750 sPwmOutForSendPWM.period_us(1000 / aFrequencyKHz);
1753 # endif // defined(SEND_PWM_BY_TIMER)
1761 #elif defined(ARDUINO_ARCH_RP2040) // Raspberry Pi Pico, Adafruit Feather RP2040, etc.
1762 #include "pico/time.h"
1764 repeating_timer_t s50usTimer;
1772 bool IRTimerInterruptHandlerHelper(repeating_timer_t*) {
1778 add_repeating_timer_us(-(
MICROS_PER_TICK), IRTimerInterruptHandlerHelper,
nullptr, &s50usTimer);
1781 cancel_repeating_timer(&s50usTimer);
1788 # if defined(SEND_PWM_BY_TIMER)
1789 #include "hardware/pwm.h"
1791 uint sSliceNumberForSendPWM;
1792 uint sChannelNumberForSendPWM;
1793 uint sIROutPuseWidth;
1799 pwm_set_counter(sSliceNumberForSendPWM, 0);
1800 pwm_set_chan_level(sSliceNumberForSendPWM, sChannelNumberForSendPWM, sIROutPuseWidth);
1803 pwm_set_chan_level(sSliceNumberForSendPWM, sChannelNumberForSendPWM, 0);
1811 # if defined(IR_SEND_PIN)
1814 sSliceNumberForSendPWM = pwm_gpio_to_slice_num(
IR_SEND_PIN);
1815 sChannelNumberForSendPWM = pwm_gpio_to_channel(
IR_SEND_PIN);
1822 uint16_t tPWMWrapValue = (clock_get_hz(clk_sys)) / (aFrequencyKHz * 1000);
1824 pwm_config tPWMConfig = pwm_get_default_config();
1825 pwm_config_set_wrap(&tPWMConfig, tPWMWrapValue - 1);
1826 pwm_init(sSliceNumberForSendPWM, &tPWMConfig,
false);
1828 pwm_set_chan_level(sSliceNumberForSendPWM, sChannelNumberForSendPWM, 0);
1829 pwm_set_enabled(sSliceNumberForSendPWM,
true);
1831 # endif // defined(SEND_PWM_BY_TIMER)
1836 #elif defined(NRF5) || defined(ARDUINO_ARCH_NRF52840) || defined(ARDUINO_ARCH_NRF52)
1837 # if defined(SEND_PWM_BY_TIMER)
1838 #error PWM generation by hardware not implemented for NRF5
1842 NVIC_EnableIRQ (TIMER2_IRQn);
1845 NVIC_DisableIRQ (TIMER2_IRQn);
1854 NRF_TIMER2->MODE = TIMER_MODE_MODE_Timer;
1855 NRF_TIMER2->TASKS_CLEAR = 1;
1856 NRF_TIMER2->PRESCALER = 4;
1857 NRF_TIMER2->BITMODE = TIMER_BITMODE_BITMODE_16Bit;
1859 NRF_TIMER2->CC[1] = 0;
1862 NRF_TIMER2->INTENSET = (TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos);
1863 NRF_TIMER2->TASKS_START = 1;
1868 #if !defined(DISABLE_CODE_FOR_RECEIVER)
1873 void TIMER2_IRQHandler(
void) {
1875 if ((NRF_TIMER2->EVENTS_COMPARE[0] != 0) && ((NRF_TIMER2->INTENSET & TIMER_INTENSET_COMPARE0_Msk) != 0)) {
1876 NRF_TIMER2->EVENTS_COMPARE[0] = 0;
1878 NRF_TIMER2->CC[0] += 50;
1891 #elif defined(__STM32F1__) || defined(ARDUINO_ARCH_STM32F1)
1892 #include <HardwareTimer.h>
1893 # if defined(SEND_PWM_BY_TIMER)
1894 #error PWM generation by hardware not implemented for STM32
1901 HardwareTimer s50usTimer(3);
1904 s50usTimer.resume();
1916 s50usTimer.setMode(TIMER_CH1, TIMER_OUTPUT_COMPARE);
1917 s50usTimer.setPrescaleFactor(1);
1920 s50usTimer.refresh();
1929 #elif defined(STM32F1xx) || defined(ARDUINO_ARCH_STM32)
1930 #include <HardwareTimer.h>
1931 # if defined(SEND_PWM_BY_TIMER)
1932 #error PWM generation by hardware not implemented for STM32
1940 HardwareTimer s50usTimer(TIM4);
1942 HardwareTimer s50usTimer(TIM2);
1946 s50usTimer.resume();
1960 s50usTimer.resume();
1967 #elif defined(PARTICLE)
1968 # ifndef __INTERVALTIMER_H__
1969 #include "SparkIntervalTimer.h"
1972 extern IntervalTimer timer;
1973 extern int ir_out_kHz;
1990 # if defined(SEND_PWM_BY_TIMER)
1991 # if defined(IR_SEND_PIN)
2014 # if defined(IR_SEND_PIN)
2019 ir_out_kHz = aFrequencyKHz;
2021 # endif // defined(SEND_PWM_BY_TIMER)
2027 #error Internal code configuration error, no timer functions implemented for this CPU / board
2038 #define ISR() void notImplemented(void)
2043 # if defined(SEND_PWM_BY_TIMER)
2051 # if defined(IR_SEND_PIN)
2056 (void) aFrequencyKHz;
2058 # endif // defined(SEND_PWM_BY_TIMER)
2060 #endif // defined(DOXYGEN / CPU_TYPES)
2064 #endif // _IR_TIMER_HPP