120
120
#define IR_USE_AVR_TIMER1 // send pin = pin 6
121
121
# endif
122
122
123
+ #elif defined(__AVR_ATtiny87__ ) || defined(__AVR_ATtiny167__ )
124
+ # if !defined(IR_USE_AVR_TIMER1 )
125
+ #define IR_USE_AVR_TIMER1
126
+ # endif
127
+ #define USE_TIMER_CHANNEL_B // send pin = pin PB1
128
+
123
129
//ATtiny85
124
130
#elif defined(__AVR_ATtiny85__ )
125
131
# if !defined(IR_USE_AVR_TIMER_TINY0 ) && !defined(IR_USE_AVR_TIMER_TINY1 )
246
252
#define IR_SEND_PIN 13
247
253
248
254
# elif defined(__AVR_ATtiny84__ )
249
- # define IR_SEND_PIN 6
255
+ #define IR_SEND_PIN 6
256
+
257
+ # elif defined(__AVR_ATtiny87__ ) || defined(__AVR_ATtiny167__ )
258
+ #define IR_SEND_PIN PIN_PB1 // OC1BU at ATTinyCore (BU/PB1, BV/PB3, BW/PB5 and BX/PB7 are available) see ENABLE_SEND_PWM_BY_TIMER
250
259
251
260
# else
252
261
#define IR_SEND_PIN 9 // OC1A Arduino Duemilanove, Diecimila, LilyPad, Sparkfun Pro Micro, Leonardo, MH-ET Tiny88 etc.
253
262
# endif // defined(CORE_OC1A_PIN)
254
- # endif // defined(SEND_PWM_BY_TIMER)
255
263
256
- #define TIMER_RESET_INTR_PENDING
264
+ # if defined(__AVR_ATtiny87__ ) || defined(__AVR_ATtiny167__ )
265
+ // Clear OC1A/OC1B on Compare Match when up-counting. Set OC1A/OC1B on Compare Match when downcounting.
266
+ #define ENABLE_SEND_PWM_BY_TIMER TCNT1 = 0; (TCCR1A |= _BV(COM1A1); (TCCR1D |= _BV(OC1BU)) // + enable OC1BU as output
267
+ #define DISABLE_SEND_PWM_BY_TIMER (TCCR1D = 0)
268
+ # else
257
269
#define ENABLE_SEND_PWM_BY_TIMER TCNT1 = 0; (TCCR1A |= _BV(COM1A1)) // Clear OC1A/OC1B on Compare Match when up-counting. Set OC1A/OC1B on Compare Match when downcounting.
258
270
#define DISABLE_SEND_PWM_BY_TIMER (TCCR1A &= ~(_BV(COM1A1)))
271
+ # endif
272
+ # endif // defined(SEND_PWM_BY_TIMER)
273
+
274
+ #define TIMER_RESET_INTR_PENDING
259
275
260
276
# if defined(__AVR_ATmega8__ ) || defined(__AVR_ATmega8515__ ) \
261
277
|| defined(__AVR_ATmega8535__ ) || defined(__AVR_ATmega16__ ) \
268
284
#define TIMER_DISABLE_RECEIVE_INTR (TIMSK1 = 0)
269
285
# endif
270
286
271
- # if defined(TIMER1_COMPA_vect )
287
+ # if defined(USE_TIMER_CHANNEL_B )
288
+ # if defined(TIMER1_COMPB_vect )
289
+ #define TIMER_INTR_NAME TIMER1_COMPB_vect
290
+ # elif defined(TIM1_COMPB_vect )
291
+ #define TIMER_INTR_NAME TIM1_COMPB_vect
292
+ # endif
293
+ #else
294
+ # if defined(TIMER1_COMPA_vect )
272
295
#define TIMER_INTR_NAME TIMER1_COMPA_vect
273
- # elif defined(TIM1_COMPA_vect )
296
+ # elif defined(TIM1_COMPA_vect )
274
297
#define TIMER_INTR_NAME TIM1_COMPA_vect
298
+ # endif
275
299
# endif
276
300
277
301
void timerConfigForSend (uint8_t aFrequencyKHz ) {
@@ -280,14 +304,22 @@ void timerConfigForSend(uint8_t aFrequencyKHz) {
280
304
TCCR1A = _BV (WGM11 );// PWM, Phase Correct, Top is ICR1
281
305
TCCR1B = _BV (WGM13 ) | _BV (CS10 );// CS10 -> no prescaling
282
306
ICR1 = pwmval - 1 ;
307
+ # if defined(USE_TIMER_CHANNEL_B )
308
+ OCR1A = ((pwmval * IR_SEND_DUTY_CYCLE ) / 100 ) - 1 ;
309
+ # else
283
310
OCR1A = ((pwmval * IR_SEND_DUTY_CYCLE ) / 100 ) - 1 ;
311
+ # endif
284
312
TCNT1 = 0 ;// not really required, since we have an 8 bit counter, but makes the signal more reproducible
285
313
# else
286
314
const uint16_t pwmval = ((F_CPU / 8 ) / 2000 ) / (aFrequencyKHz ); // 2000 instead of 1000 because of Phase Correct PWM
287
315
TCCR1A = _BV (WGM11 );// PWM, Phase Correct, Top is ICR1
288
316
TCCR1B = _BV (WGM13 ) | _BV (CS11 );// CS11 -> Prescaling by 8
289
317
ICR1 = pwmval - 1 ;
318
+ # if defined(USE_TIMER_CHANNEL_B )
290
319
OCR1A = ((pwmval * IR_SEND_DUTY_CYCLE ) / 100 ) - 1 ;
320
+ # else
321
+ OCR1A = ((pwmval * IR_SEND_DUTY_CYCLE ) / 100 ) - 1 ;
322
+ # endif
291
323
TCNT1 = 0 ;// not really required, since we have an 8 bit counter, but makes the signal more reproducible
292
324
# endif
293
325
}
@@ -320,11 +352,12 @@ void timerConfigForReceive() {
320
352
# else
321
353
#define IR_SEND_PIN 3 // Arduino Duemilanove, Diecimila, LilyPad, etc
322
354
# endif // defined(CORE_OC2B_PIN)
323
- # endif
324
355
325
- #define TIMER_RESET_INTR_PENDING
326
356
#define ENABLE_SEND_PWM_BY_TIMER TCNT2 = 0; (TCCR2A |= _BV(COM2B1)) // Clear OC2B on Compare Match
327
357
#define DISABLE_SEND_PWM_BY_TIMER (TCCR2A &= ~(_BV(COM2B1))) // Normal port operation, OC2B disconnected.
358
+ # endif // defined(SEND_PWM_BY_TIMER)
359
+
360
+ #define TIMER_RESET_INTR_PENDING
328
361
#define TIMER_ENABLE_RECEIVE_INTR (TIMSK2 = _BV(OCIE2B)) // Output Compare Match A Interrupt Enable
329
362
#define TIMER_DISABLE_RECEIVE_INTR (TIMSK2 = 0)
330
363
#define TIMER_INTR_NAME TIMER2_COMPB_vect // We use TIMER2_COMPB_vect to be compatible with tone() library
@@ -391,11 +424,12 @@ void timerConfigForReceive() {
391
424
# else
392
425
#error Please add OC3A pin number here
393
426
# endif
394
- # endif
395
427
396
- #define TIMER_RESET_INTR_PENDING
397
428
#define ENABLE_SEND_PWM_BY_TIMER TCNT3 = 0; (TCCR3A |= _BV(COM3A1))
398
429
#define DISABLE_SEND_PWM_BY_TIMER (TCCR3A &= ~(_BV(COM3A1)))
430
+ # endif
431
+
432
+ #define TIMER_RESET_INTR_PENDING
399
433
#define TIMER_ENABLE_RECEIVE_INTR (TIMSK3 = _BV(OCIE3B))
400
434
#define TIMER_DISABLE_RECEIVE_INTR (TIMSK3 = 0)
401
435
#define TIMER_INTR_NAME TIMER3_COMPB_vect
@@ -432,11 +466,12 @@ void timerConfigForReceive() {
432
466
# else
433
467
#error Please add OC4A pin number here
434
468
# endif
435
- # endif
436
469
437
- #define TIMER_RESET_INTR_PENDING
438
470
#define ENABLE_SEND_PWM_BY_TIMER TCNT4 = 0; (TCCR4A |= _BV(COM4A1))
439
471
#define DISABLE_SEND_PWM_BY_TIMER (TCCR4A &= ~(_BV(COM4A1)))
472
+ # endif
473
+
474
+ #define TIMER_RESET_INTR_PENDING
440
475
#define TIMER_ENABLE_RECEIVE_INTR (TIMSK4 = _BV(OCIE4A))
441
476
#define TIMER_DISABLE_RECEIVE_INTR (TIMSK4 = 0)
442
477
#define TIMER_INTR_NAME TIMER4_COMPA_vect
@@ -474,17 +509,18 @@ void timerConfigForReceive() {
474
509
# else
475
510
#error Please add OC4A pin number here
476
511
# endif
477
- # endif
478
512
479
- #define TIMER_RESET_INTR_PENDING
480
- # if defined(ARDUINO_AVR_PROMICRO ) // Sparkfun Pro Micro
513
+ # if defined(ARDUINO_AVR_PROMICRO ) // Sparkfun Pro Micro
481
514
#define ENABLE_SEND_PWM_BY_TIMER TCNT4 = 0; (TCCR4A |= _BV(COM4A0)) // Use complementary OC4A output on pin 5
482
515
#define DISABLE_SEND_PWM_BY_TIMER (TCCR4A &= ~(_BV(COM4A0))) // (Pro Micro does not map PC7 (32/ICP3/CLK0/OC4A)
483
516
// of ATmega32U4 )
484
- # else
517
+ # else
485
518
#define ENABLE_SEND_PWM_BY_TIMER TCNT4 = 0; (TCCR4A |= _BV(COM4A1))
486
519
#define DISABLE_SEND_PWM_BY_TIMER (TCCR4A &= ~(_BV(COM4A1)))
520
+ # endif
487
521
# endif
522
+
523
+ #define TIMER_RESET_INTR_PENDING
488
524
#define TIMER_ENABLE_RECEIVE_INTR (TIMSK4 = _BV(TOIE4))
489
525
#define TIMER_DISABLE_RECEIVE_INTR (TIMSK4 = 0)
490
526
#define TIMER_INTR_NAME TIMER4_OVF_vect
@@ -530,11 +566,12 @@ void timerConfigForReceive() {
530
566
# else
531
567
#error Please add OC5A pin number here
532
568
# endif
533
- # endif
534
569
535
- #define TIMER_RESET_INTR_PENDING
536
570
#define ENABLE_SEND_PWM_BY_TIMER TCNT5 = 0; (TCCR5A |= _BV(COM5A1))
537
571
#define DISABLE_SEND_PWM_BY_TIMER (TCCR5A &= ~(_BV(COM5A1)))
572
+ # endif
573
+
574
+ #define TIMER_RESET_INTR_PENDING
538
575
#define TIMER_ENABLE_RECEIVE_INTR (TIMSK5 = _BV(OCIE5A))
539
576
#define TIMER_DISABLE_RECEIVE_INTR (TIMSK5 = 0)
540
577
#define TIMER_INTR_NAME TIMER5_COMPA_vect
@@ -564,11 +601,12 @@ void timerConfigForReceive() {
564
601
#elif defined(IR_USE_AVR_TIMER_TINY0 )
565
602
# if defined(SEND_PWM_BY_TIMER )
566
603
#define IR_SEND_PIN 1
567
- # endif
568
604
569
- #define TIMER_RESET_INTR_PENDING
570
605
#define ENABLE_SEND_PWM_BY_TIMER TCNT0 = 0; (TCCR0A |= _BV(COM0B1))
571
606
#define DISABLE_SEND_PWM_BY_TIMER (TCCR0A &= ~(_BV(COM0B1)))
607
+ # endif
608
+
609
+ #define TIMER_RESET_INTR_PENDING
572
610
#define TIMER_ENABLE_RECEIVE_INTR (TIMSK |= _BV(OCIE0A))
573
611
#define TIMER_DISABLE_RECEIVE_INTR (TIMSK &= ~(_BV(OCIE0A)))
574
612
#define TIMER_INTR_NAME TIMER0_COMPA_vect
@@ -606,11 +644,12 @@ void timerConfigForReceive() {
606
644
#elif defined(IR_USE_AVR_TIMER_TINY1 )
607
645
# if defined(SEND_PWM_BY_TIMER )
608
646
#define IR_SEND_PIN 4
609
- # endif
610
647
611
- #define TIMER_RESET_INTR_PENDING
612
648
#define ENABLE_SEND_PWM_BY_TIMER TCNT1 = 0; GTCCR |= _BV(PWM1B) | _BV(COM1B0) // Enable pin 4 PWM output (PB4 - Arduino D4)
613
649
#define DISABLE_SEND_PWM_BY_TIMER (GTCCR &= ~(_BV(PWM1B) | _BV(COM1B0)))
650
+ # endif
651
+
652
+ #define TIMER_RESET_INTR_PENDING
614
653
#define TIMER_ENABLE_RECEIVE_INTR (TIMSK |= _BV(OCIE1B))
615
654
#define TIMER_DISABLE_RECEIVE_INTR (TIMSK &= ~(_BV(OCIE1B)))
616
655
#define TIMER_INTR_NAME TIMER1_COMPB_vect
@@ -654,12 +693,13 @@ void timerConfigForReceive() {
654
693
#elif defined(IR_USE_AVR_TIMER_B )
655
694
# if defined(SEND_PWM_BY_TIMER )
656
695
#define IR_SEND_PIN A4 // PA2 - A4 on Nano Every, PA5 on ATtiny1604
696
+
697
+ #define ENABLE_SEND_PWM_BY_TIMER TCB0.CNT = 0; (TCB0.CTRLB |= TCB_CCMPEN_bm)
698
+ #define DISABLE_SEND_PWM_BY_TIMER (TCB0.CTRLB &= ~(TCB_CCMPEN_bm))
657
699
# endif
658
700
659
701
// ATmega4809 TCB0
660
702
#define TIMER_RESET_INTR_PENDING TCB0.INTFLAGS = TCB_CAPT_bm
661
- #define ENABLE_SEND_PWM_BY_TIMER TCB0.CNT = 0; (TCB0.CTRLB |= TCB_CCMPEN_bm)
662
- #define DISABLE_SEND_PWM_BY_TIMER (TCB0.CTRLB &= ~(TCB_CCMPEN_bm))
663
703
#define TIMER_ENABLE_RECEIVE_INTR (TCB0.INTCTRL = TCB_CAPT_bm)
664
704
#define TIMER_DISABLE_RECEIVE_INTR (TCB0.INTCTRL &= ~(TCB_CAPT_bm))
665
705
#define TIMER_INTR_NAME TCB0_INT_vect
@@ -690,11 +730,12 @@ void timerConfigForReceive() {
690
730
#elif defined(IR_USE_AVR_TIMER_D )
691
731
# if defined(SEND_PWM_BY_TIMER )
692
732
#define IR_SEND_PIN 13
693
- # endif
694
733
695
- #define TIMER_RESET_INTR_PENDING (TCD0.INTFLAGS = TCD_OVF_bm)
696
734
#define ENABLE_SEND_PWM_BY_TIMER (timerEnablSendPWM())
697
735
#define DISABLE_SEND_PWM_BY_TIMER (TCD0.CTRLA = 0) // do not disable output, disable complete timer
736
+ # endif
737
+
738
+ #define TIMER_RESET_INTR_PENDING (TCD0.INTFLAGS = TCD_OVF_bm)
698
739
#define TIMER_ENABLE_RECEIVE_INTR (TCD0.INTCTRL = TCD_OVF_bm)
699
740
#define TIMER_DISABLE_RECEIVE_INTR (TCD0.INTCTRL = 0)
700
741
#define TIMER_INTR_NAME TCD0_OVF_vect
@@ -754,12 +795,13 @@ void timerConfigForReceive() {
754
795
#elif defined(__MK20DX128__ ) || defined(__MK20DX256__ ) || defined(__MK64FX512__ ) || defined(__MK66FX1M0__ )
755
796
# if defined(SEND_PWM_BY_TIMER )
756
797
#define IR_SEND_PIN 5
798
+
799
+ #define ENABLE_SEND_PWM_BY_TIMER do { CORE_PIN5_CONFIG = PORT_PCR_MUX(2) | PORT_PCR_DSE | PORT_PCR_SRE; } while(0)
800
+ #define DISABLE_SEND_PWM_BY_TIMER do { CORE_PIN5_CONFIG = PORT_PCR_MUX(1) | PORT_PCR_DSE | PORT_PCR_SRE; } while(0)
757
801
# endif
758
802
759
803
// Special carrier modulator timer for Teensy 3.0 / Teensy 3.1
760
804
#define TIMER_RESET_INTR_PENDING uint8_t tmp __attribute__((unused)) = CMT_MSC; CMT_CMD2 = 30
761
- #define ENABLE_SEND_PWM_BY_TIMER do { CORE_PIN5_CONFIG = PORT_PCR_MUX(2) | PORT_PCR_DSE | PORT_PCR_SRE; } while(0)
762
- #define DISABLE_SEND_PWM_BY_TIMER do { CORE_PIN5_CONFIG = PORT_PCR_MUX(1) | PORT_PCR_DSE | PORT_PCR_SRE; } while(0)
763
805
#define TIMER_ENABLE_RECEIVE_INTR NVIC_ENABLE_IRQ(IRQ_CMT)
764
806
#define TIMER_DISABLE_RECEIVE_INTR NVIC_DISABLE_IRQ(IRQ_CMT)
765
807
#define TIMER_INTR_NAME cmt_isr
@@ -807,12 +849,13 @@ void timerConfigForReceive() {
807
849
#elif defined(__MKL26Z64__ )
808
850
# if defined(SEND_PWM_BY_TIMER )
809
851
#define IR_SEND_PIN 16
852
+
853
+ #define ENABLE_SEND_PWM_BY_TIMER FTM1_CNT = 0; CORE_PIN16_CONFIG = PORT_PCR_MUX(3)|PORT_PCR_DSE|PORT_PCR_SRE
854
+ #define DISABLE_SEND_PWM_BY_TIMER CORE_PIN16_CONFIG = PORT_PCR_MUX(1)|PORT_PCR_SRE
810
855
# endif
811
856
812
857
// defines for TPM1 timer on Teensy-LC
813
858
#define TIMER_RESET_INTR_PENDING FTM1_SC |= FTM_SC_TOF;
814
- #define ENABLE_SEND_PWM_BY_TIMER FTM1_CNT = 0; CORE_PIN16_CONFIG = PORT_PCR_MUX(3)|PORT_PCR_DSE|PORT_PCR_SRE
815
- #define DISABLE_SEND_PWM_BY_TIMER CORE_PIN16_CONFIG = PORT_PCR_MUX(1)|PORT_PCR_SRE
816
859
#define TIMER_ENABLE_RECEIVE_INTR NVIC_ENABLE_IRQ(IRQ_FTM1)
817
860
#define TIMER_DISABLE_RECEIVE_INTR NVIC_DISABLE_IRQ(IRQ_FTM1)
818
861
#define TIMER_INTR_NAME ftm1_isr
@@ -873,22 +916,25 @@ void timerConfigForReceive() {
873
916
}
874
917
875
918
/***************************************
876
- * ESP32 boards
919
+ * ESP32 boards - can use any pin for timer
877
920
***************************************/
878
921
#elif defined(ESP32 )
879
- # if defined(SEND_PWM_BY_TIMER )
922
+ //# if defined(SEND_PWM_BY_TIMER)
923
+ #if !defined(IR_SEND_PIN )
880
924
#define IR_SEND_PIN 4 // can use any pin, no timer restrictions
881
- # endif
925
+ #endif
926
+
927
+ #define ENABLE_SEND_PWM_BY_TIMER ledcWrite(LED_CHANNEL, IR_SEND_DUTY_CYCLE) // we must use channel here not pin number
928
+ #define DISABLE_SEND_PWM_BY_TIMER ledcWrite(LED_CHANNEL, 0)
929
+ //# endif
882
930
883
931
# if ! defined(LED_CHANNEL )
884
932
#define LED_CHANNEL 0 // The channel used for PWM 0 to 7 are high speed PWM channels
885
933
# endif
886
934
935
+ #define TIMER_RESET_INTR_PENDING
887
936
#define TIMER_ENABLE_RECEIVE_INTR timerAlarmEnable(timer)
888
937
#define TIMER_DISABLE_RECEIVE_INTR timerEnd(timer); timerDetachInterrupt(timer)
889
- #define TIMER_RESET_INTR_PENDING
890
- #define ENABLE_SEND_PWM_BY_TIMER ledcWrite(LED_CHANNEL, IR_SEND_DUTY_CYCLE) // we must use channel here not pin number
891
- #define DISABLE_SEND_PWM_BY_TIMER ledcWrite(LED_CHANNEL, 0)
892
938
// Redefinition of ISR macro which creates a plain function now
893
939
# ifdef ISR
894
940
#undef ISR
@@ -1152,6 +1198,9 @@ void timerConfigForReceive() {
1152
1198
1153
1199
# if defined(SEND_PWM_BY_TIMER )
1154
1200
#define IR_SEND_PIN A5 // Particle supports multiple pins
1201
+
1202
+ #define ENABLE_SEND_PWM_BY_TIMER analogWrite(IrSender.sendPin, 128, ir_out_kHz*1000)
1203
+ #define DISABLE_SEND_PWM_BY_TIMER analogWrite(IrSender.sendPin, 0, ir_out_kHz*1000)
1155
1204
# endif
1156
1205
1157
1206
# ifndef IR_OUT_KHZ
@@ -1163,8 +1212,6 @@ extern int ir_out_kHz;
1163
1212
//void IRTimerInterruptHandler();
1164
1213
1165
1214
#define TIMER_RESET_INTR_PENDING
1166
- #define ENABLE_SEND_PWM_BY_TIMER analogWrite(IrSender.sendPin, 128, ir_out_kHz*1000)
1167
- #define DISABLE_SEND_PWM_BY_TIMER analogWrite(IrSender.sendPin, 0, ir_out_kHz*1000)
1168
1215
#define TIMER_ENABLE_RECEIVE_INTR timer.begin(IRTimerInterruptHandler, MICROS_PER_TICK, uSec)
1169
1216
#define TIMER_DISABLE_RECEIVE_INTR timer.end()
1170
1217
0 commit comments