/* * IRremote * Version 0.1 July, 2009 * Copyright 2009 Ken Shirriff * For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html * * Modified by Paul Stoffregen to support other boards and timers * * Interrupt code based on NECIRrcv by Joe Knapp * http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556 * Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/ * * JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post) */ #ifndef _IRSENDREVINT_H_ #define _IRSENDREVINT_H_ #if defined(ARDUINO) && ARDUINO >= 100 #include #else #include #endif // define which timer to use // // Uncomment the timer you wish to use on your board. If you // are using another library which uses timer2, you have options // to switch IRremote to use a different timer. // Arduino Mega #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) //#define IR_USE_TIMER1 // tx = pin 11 #define IR_USE_TIMER2 // tx = pin 9 //#define IR_USE_TIMER3 // tx = pin 5 //#define IR_USE_TIMER4 // tx = pin 6 //#define IR_USE_TIMER5 // tx = pin 46 // Teensy 1.0 #elif defined(__AVR_AT90USB162__) #define IR_USE_TIMER1 // tx = pin 17 // Teensy 2.0 #elif defined(__AVR_ATmega32U4__) //#define IR_USE_TIMER1 // tx = pin 14 //#define IR_USE_TIMER3 // tx = pin 9 #define IR_USE_TIMER4_HS // tx = pin 10 // Teensy++ 1.0 & 2.0 #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) //#define IR_USE_TIMER1 // tx = pin 25 #define IR_USE_TIMER2 // tx = pin 1 //#define IR_USE_TIMER3 // tx = pin 16 // Sanguino #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) //#define IR_USE_TIMER1 // tx = pin 13 #define IR_USE_TIMER2 // tx = pin 14 // Atmega8 #elif defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__) #define IR_USE_TIMER1 // tx = pin 9 // Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, etc #else //#define IR_USE_TIMER1 // tx = pin 9 #define IR_USE_TIMER2 // tx = pin 3 #endif #ifdef F_CPU #define SYSCLOCK F_CPU // main Arduino clock #else #define SYSCLOCK 16000000 // main Arduino clock #endif #define ERR 0 #define DECODED 1 // defines for setting and clearing register bits #ifndef cbi #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) #endif #ifndef sbi #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) #endif #define TOLERANCE 25 // percent tolerance in measurements #define LTOL (1.0 - TOLERANCE/100.) #define UTOL (1.0 + TOLERANCE/100.) #define _GAP 5000 // Minimum map between transmissions #define GAP_TICKS (_GAP/USECPERTICK) #define TICKS_LOW(us) (int) (((us)*LTOL/USECPERTICK)) #define TICKS_HIGH(us) (int) (((us)*UTOL/USECPERTICK + 1)) // receiver states #define STATE_IDLE 2 #define STATE_MARK 3 #define STATE_SPACE 4 #define STATE_STOP 5 // information for the interrupt handler typedef struct { uint8_t recvpin; // pin for IR data from detector uint8_t rcvstate; // state machine unsigned int timer; // state timer, counts 50uS ticks. unsigned int rawbuf[RAWBUF]; // raw data uint8_t rawlen; // counter of entries in rawbuf } irparams_t; // Defined in IRremote.cpp extern volatile irparams_t irparams; // IR detector output is active low #define MARK 0 #define SPACE 1 #define TOPBIT 0x80000000 // defines for timer2 (8 bits) #if defined(IR_USE_TIMER2) #define TIMER_RESET #define TIMER_ENABLE_PWM (TCCR2A |= _BV(COM2B1)) #define TIMER_DISABLE_PWM (TCCR2A &= ~(_BV(COM2B1))) #define TIMER_ENABLE_INTR (TIMSK2 = _BV(OCIE2A)) #define TIMER_DISABLE_INTR (TIMSK2 = 0) #define TIMER_INTR_NAME TIMER2_COMPA_vect #define TIMER_CONFIG_KHZ(val) ({ \ const uint8_t pwmval = SYSCLOCK / 2000 / (val); \ TCCR2A = _BV(WGM20); \ TCCR2B = _BV(WGM22) | _BV(CS20); \ OCR2A = pwmval; \ OCR2B = pwmval / (100/10); \ }) #define TIMER_COUNT_TOP (SYSCLOCK * USECPERTICK / 1000000) #if (TIMER_COUNT_TOP < 256) #define TIMER_CONFIG_NORMAL() ({ \ TCCR2A = _BV(WGM21); \ TCCR2B = _BV(CS20); \ OCR2A = TIMER_COUNT_TOP; \ TCNT2 = 0; \ }) #else #define TIMER_CONFIG_NORMAL() ({ \ TCCR2A = _BV(WGM21); \ TCCR2B = _BV(CS21); \ OCR2A = TIMER_COUNT_TOP / 8; \ TCNT2 = 0; \ }) #endif #if defined(CORE_OC2B_PIN) #define TIMER_PWM_PIN CORE_OC2B_PIN /* Teensy */ #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) #define TIMER_PWM_PIN 9 /* Arduino Mega */ #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) #define TIMER_PWM_PIN 14 /* Sanguino */ #else #define TIMER_PWM_PIN 3 /* Arduino Duemilanove, Diecimi */ /* la, LilyPad, etc */ #endif // defines for timer1 (16 bits) #elif defined(IR_USE_TIMER1) #define TIMER_RESET #define TIMER_ENABLE_PWM (TCCR1A |= _BV(COM1A1)) #define TIMER_DISABLE_PWM (TCCR1A &= ~(_BV(COM1A1))) #if defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__) #define TIMER_ENABLE_INTR (TIMSK = _BV(OCIE1A)) #define TIMER_DISABLE_INTR (TIMSK = 0) #else #define TIMER_ENABLE_INTR (TIMSK1 = _BV(OCIE1A)) #define TIMER_DISABLE_INTR (TIMSK1 = 0) #endif #define TIMER_INTR_NAME TIMER1_COMPA_vect #define TIMER_CONFIG_KHZ(val) ({ \ const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ TCCR1A = _BV(WGM11); \ TCCR1B = _BV(WGM13) | _BV(CS10); \ ICR1 = pwmval; \ OCR1A = pwmval / 3; \ }) #define TIMER_CONFIG_NORMAL() ({ \ TCCR1A = 0; \ TCCR1B = _BV(WGM12) | _BV(CS10); \ OCR1A = SYSCLOCK * USECPERTICK / 1000000; \ TCNT1 = 0; \ }) #if defined(CORE_OC1A_PIN) #define TIMER_PWM_PIN CORE_OC1A_PIN /* Teensy */ #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) #define TIMER_PWM_PIN 11 /* Arduino Mega */ #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) #define TIMER_PWM_PIN 13 /* Sanguino */ #else #define TIMER_PWM_PIN 9 /* Arduino Duemilanove, Diecimi */ /* la, LilyPad, etc */ #endif // defines for timer3 (16 bits) #elif defined(IR_USE_TIMER3) #define TIMER_RESET #define TIMER_ENABLE_PWM (TCCR3A |= _BV(COM3A1)) #define TIMER_DISABLE_PWM (TCCR3A &= ~(_BV(COM3A1))) #define TIMER_ENABLE_INTR (TIMSK3 = _BV(OCIE3A)) #define TIMER_DISABLE_INTR (TIMSK3 = 0) #define TIMER_INTR_NAME TIMER3_COMPA_vect #define TIMER_CONFIG_KHZ(val) ({ \ const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ TCCR3A = _BV(WGM31); \ TCCR3B = _BV(WGM33) | _BV(CS30); \ ICR3 = pwmval; \ OCR3A = pwmval / 3; \ }) #define TIMER_CONFIG_NORMAL() ({ \ TCCR3A = 0; \ TCCR3B = _BV(WGM32) | _BV(CS30); \ OCR3A = SYSCLOCK * USECPERTICK / 1000000; \ TCNT3 = 0; \ }) #if defined(CORE_OC3A_PIN) #define TIMER_PWM_PIN CORE_OC3A_PIN /* Teensy */ #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) #define TIMER_PWM_PIN 5 /* Arduino Mega */ #else #error "Please add OC3A pin number here\n" #endif // defines for timer4 (10 bits, high speed option) #elif defined(IR_USE_TIMER4_HS) #define TIMER_RESET #define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1)) #define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1))) #define TIMER_ENABLE_INTR (TIMSK4 = _BV(TOIE4)) #define TIMER_DISABLE_INTR (TIMSK4 = 0) #define TIMER_INTR_NAME TIMER4_OVF_vect #define TIMER_CONFIG_KHZ(val) ({ \ const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ TCCR4A = (1<> 8; \ OCR4C = pwmval; \ TC4H = (pwmval / 3) >> 8; \ OCR4A = (pwmval / 3) & 255; \ }) #define TIMER_CONFIG_NORMAL() ({ \ TCCR4A = 0; \ TCCR4B = _BV(CS40); \ TCCR4C = 0; \ TCCR4D = 0; \ TCCR4E = 0; \ TC4H = (SYSCLOCK * USECPERTICK / 1000000) >> 8; \ OCR4C = (SYSCLOCK * USECPERTICK / 1000000) & 255; \ TC4H = 0; \ TCNT4 = 0; \ }) #if defined(CORE_OC4A_PIN) #define TIMER_PWM_PIN CORE_OC4A_PIN /* Teensy */ #else #error "Please add OC4A pin number here\n" #endif // defines for timer4 (16 bits) #elif defined(IR_USE_TIMER4) #define TIMER_RESET #define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1)) #define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1))) #define TIMER_ENABLE_INTR (TIMSK4 = _BV(OCIE4A)) #define TIMER_DISABLE_INTR (TIMSK4 = 0) #define TIMER_INTR_NAME TIMER4_COMPA_vect #define TIMER_CONFIG_KHZ(val) ({ \ const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ TCCR4A = _BV(WGM41); \ TCCR4B = _BV(WGM43) | _BV(CS40); \ ICR4 = pwmval; \ OCR4A = pwmval / 3; \ }) #define TIMER_CONFIG_NORMAL() ({ \ TCCR4A = 0; \ TCCR4B = _BV(WGM42) | _BV(CS40); \ OCR4A = SYSCLOCK * USECPERTICK / 1000000; \ TCNT4 = 0; \ }) #if defined(CORE_OC4A_PIN) #define TIMER_PWM_PIN CORE_OC4A_PIN #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) #define TIMER_PWM_PIN 6 /* Arduino Mega */ #else #error "Please add OC4A pin number here\n" #endif // defines for timer5 (16 bits) #elif defined(IR_USE_TIMER5) #define TIMER_RESET #define TIMER_ENABLE_PWM (TCCR5A |= _BV(COM5A1)) #define TIMER_DISABLE_PWM (TCCR5A &= ~(_BV(COM5A1))) #define TIMER_ENABLE_INTR (TIMSK5 = _BV(OCIE5A)) #define TIMER_DISABLE_INTR (TIMSK5 = 0) #define TIMER_INTR_NAME TIMER5_COMPA_vect #define TIMER_CONFIG_KHZ(val) ({ \ const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ TCCR5A = _BV(WGM51); \ TCCR5B = _BV(WGM53) | _BV(CS50); \ ICR5 = pwmval; \ OCR5A = pwmval / 3; \ }) #define TIMER_CONFIG_NORMAL() ({ \ TCCR5A = 0; \ TCCR5B = _BV(WGM52) | _BV(CS50); \ OCR5A = SYSCLOCK * USECPERTICK / 1000000; \ TCNT5 = 0; \ }) #if defined(CORE_OC5A_PIN) #define TIMER_PWM_PIN CORE_OC5A_PIN #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) #define TIMER_PWM_PIN 46 /* Arduino Mega */ #else #error "Please add OC5A pin number here\n" #endif #else // unknown timer #error "Internal code configuration error, no known IR_USE_TIMER# defined\n" #endif #endif