3 * Version 0.1 July, 2009
4 * Copyright 2009 Ken Shirriff
5 * For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
7 * Modified by Paul Stoffregen <paul@pjrc.com> to support other boards and timers
9 * Interrupt code based on NECIRrcv by Joe Knapp
10 * http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556
11 * Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/
13 * JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
19 #if defined(ARDUINO) && ARDUINO >= 100
25 // define which timer to use
27 // Uncomment the timer you wish to use on your board. If you
28 // are using another library which uses timer2, you have options
29 // to switch IRremote to use a different timer.
32 #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
33 //#define IR_USE_TIMER1 // tx = pin 11
34 #define IR_USE_TIMER2 // tx = pin 9
35 //#define IR_USE_TIMER3 // tx = pin 5
36 //#define IR_USE_TIMER4 // tx = pin 6
37 //#define IR_USE_TIMER5 // tx = pin 46
40 #elif defined(__AVR_AT90USB162__)
41 #define IR_USE_TIMER1 // tx = pin 17
44 #elif defined(__AVR_ATmega32U4__)
45 //#define IR_USE_TIMER1 // tx = pin 14
46 //#define IR_USE_TIMER3 // tx = pin 9
47 #define IR_USE_TIMER4_HS // tx = pin 10
50 #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
51 //#define IR_USE_TIMER1 // tx = pin 25
52 #define IR_USE_TIMER2 // tx = pin 1
53 //#define IR_USE_TIMER3 // tx = pin 16
56 #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
57 //#define IR_USE_TIMER1 // tx = pin 13
58 #define IR_USE_TIMER2 // tx = pin 14
61 #elif defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__)
62 #define IR_USE_TIMER1 // tx = pin 9
64 // Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, etc
66 //#define IR_USE_TIMER1 // tx = pin 9
67 #define IR_USE_TIMER2 // tx = pin 3
73 #define SYSCLOCK F_CPU // main Arduino clock
75 #define SYSCLOCK 16000000 // main Arduino clock
82 // defines for setting and clearing register bits
84 #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
87 #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
90 // Pulse parms are *50-100 for the Mark and *50+100 for the space
91 // First MARK is the one after the long gap
92 // pulse parameters in usec
93 #define NEC_HDR_MARK 9000
94 #define NEC_HDR_SPACE 4500
95 #define NEC_BIT_MARK 560
96 #define NEC_ONE_SPACE 1600
97 #define NEC_ZERO_SPACE 560
98 #define NEC_RPT_SPACE 2250
100 #define SONY_HDR_MARK 2400
101 #define SONY_HDR_SPACE 600
102 #define SONY_ONE_MARK 1200
103 #define SONY_ZERO_MARK 600
104 #define SONY_RPT_LENGTH 45000
105 #define SONY_DOUBLE_SPACE_USECS 500 // usually ssee 713 - not using ticks as get number wrapround
108 #define SANYO_HDR_MARK 3500 // seen range 3500
109 #define SANYO_HDR_SPACE 950 // seen 950
110 #define SANYO_ONE_MARK 2400 // seen 2400
111 #define SANYO_ZERO_MARK 700 // seen 700
112 #define SANYO_DOUBLE_SPACE_USECS 800 // usually ssee 713 - not using ticks as get number wrapround
113 #define SANYO_RPT_LENGTH 45000
115 // Mitsubishi RM 75501
116 // 14200 7 41 7 42 7 42 7 17 7 17 7 18 7 41 7 18 7 17 7 17 7 18 7 41 8 17 7 17 7 18 7 17 7
118 // #define MITSUBISHI_HDR_MARK 250 // seen range 3500
119 #define MITSUBISHI_HDR_SPACE 350 // 7*50+100
120 #define MITSUBISHI_ONE_MARK 1950 // 41*50-100
121 #define MITSUBISHI_ZERO_MARK 750 // 17*50-100
122 // #define MITSUBISHI_DOUBLE_SPACE_USECS 800 // usually ssee 713 - not using ticks as get number wrapround
123 // #define MITSUBISHI_RPT_LENGTH 45000
127 #define RC5_RPT_LENGTH 46000
129 #define RC6_HDR_MARK 2666
130 #define RC6_HDR_SPACE 889
132 #define RC6_RPT_LENGTH 46000
134 #define SHARP_BIT_MARK 245
135 #define SHARP_ONE_SPACE 1805
136 #define SHARP_ZERO_SPACE 795
137 #define SHARP_GAP 600000
138 #define SHARP_TOGGLE_MASK 0x3FF
139 #define SHARP_RPT_SPACE 3000
141 #define DISH_HDR_MARK 400
142 #define DISH_HDR_SPACE 6100
143 #define DISH_BIT_MARK 400
144 #define DISH_ONE_SPACE 1700
145 #define DISH_ZERO_SPACE 2800
146 #define DISH_RPT_SPACE 6200
147 #define DISH_TOP_BIT 0x8000
149 #define PANASONIC_HDR_MARK 3502
150 #define PANASONIC_HDR_SPACE 1750
151 #define PANASONIC_BIT_MARK 502
152 #define PANASONIC_ONE_SPACE 1244
153 #define PANASONIC_ZERO_SPACE 400
155 #define JVC_HDR_MARK 8000
156 #define JVC_HDR_SPACE 4000
157 #define JVC_BIT_MARK 600
158 #define JVC_ONE_SPACE 1600
159 #define JVC_ZERO_SPACE 550
160 #define JVC_RPT_LENGTH 60000
162 #define SHARP_BITS 15
165 #define TOLERANCE 25 // percent tolerance in measurements
166 #define LTOL (1.0 - TOLERANCE/100.)
167 #define UTOL (1.0 + TOLERANCE/100.)
169 #define _GAP 5000 // Minimum map between transmissions
170 #define GAP_TICKS (_GAP/USECPERTICK)
172 #define TICKS_LOW(us) (int) (((us)*LTOL/USECPERTICK))
173 #define TICKS_HIGH(us) (int) (((us)*UTOL/USECPERTICK + 1))
176 int MATCH(int measured, int desired) {return measured >= TICKS_LOW(desired) && measured <= TICKS_HIGH(desired);}
177 int MATCH_MARK(int measured_ticks, int desired_us) {return MATCH(measured_ticks, (desired_us + MARK_EXCESS));}
178 int MATCH_SPACE(int measured_ticks, int desired_us) {return MATCH(measured_ticks, (desired_us - MARK_EXCESS));}
179 // Debugging versions are in IRremote.cpp
185 #define STATE_SPACE 4
188 // information for the interrupt handler
190 uint8_t recvpin; // pin for IR data from detector
191 uint8_t rcvstate; // state machine
192 uint8_t blinkflag; // TRUE to enable blinking of pin 13 on IR processing
193 unsigned int timer; // state timer, counts 50uS ticks.
194 unsigned int rawbuf[RAWBUF]; // raw data
195 uint8_t rawlen; // counter of entries in rawbuf
199 // Defined in IRremote.cpp
200 extern volatile irparams_t irparams;
202 // IR detector output is active low
206 #define TOPBIT 0x80000000
210 #define SANYO_BITS 12
211 #define MITSUBISHI_BITS 16
212 #define MIN_RC5_SAMPLES 11
213 #define MIN_RC6_SAMPLES 1
214 #define PANASONIC_BITS 48
220 // defines for timer2 (8 bits)
221 #if defined(IR_USE_TIMER2)
223 #define TIMER_ENABLE_PWM (TCCR2A |= _BV(COM2B1))
224 #define TIMER_DISABLE_PWM (TCCR2A &= ~(_BV(COM2B1)))
225 #define TIMER_ENABLE_INTR (TIMSK2 = _BV(OCIE2A))
226 #define TIMER_DISABLE_INTR (TIMSK2 = 0)
227 #define TIMER_INTR_NAME TIMER2_COMPA_vect
228 #define TIMER_CONFIG_KHZ(val) ({ \
229 const uint8_t pwmval = SYSCLOCK / 2000 / (val); \
230 TCCR2A = _BV(WGM20); \
231 TCCR2B = _BV(WGM22) | _BV(CS20); \
233 OCR2B = pwmval / 3; \
235 #define TIMER_COUNT_TOP (SYSCLOCK * USECPERTICK / 1000000)
236 #if (TIMER_COUNT_TOP < 256)
237 #define TIMER_CONFIG_NORMAL() ({ \
238 TCCR2A = _BV(WGM21); \
239 TCCR2B = _BV(CS20); \
240 OCR2A = TIMER_COUNT_TOP; \
244 #define TIMER_CONFIG_NORMAL() ({ \
245 TCCR2A = _BV(WGM21); \
246 TCCR2B = _BV(CS21); \
247 OCR2A = TIMER_COUNT_TOP / 8; \
251 #if defined(CORE_OC2B_PIN)
252 #define TIMER_PWM_PIN CORE_OC2B_PIN /* Teensy */
253 #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
254 #define TIMER_PWM_PIN 9 /* Arduino Mega */
255 #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
256 #define TIMER_PWM_PIN 14 /* Sanguino */
258 #define TIMER_PWM_PIN 3 /* Arduino Duemilanove, Diecimila, LilyPad, etc */
262 // defines for timer1 (16 bits)
263 #elif defined(IR_USE_TIMER1)
265 #define TIMER_ENABLE_PWM (TCCR1A |= _BV(COM1A1))
266 #define TIMER_DISABLE_PWM (TCCR1A &= ~(_BV(COM1A1)))
267 #if defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__)
268 #define TIMER_ENABLE_INTR (TIMSK = _BV(OCIE1A))
269 #define TIMER_DISABLE_INTR (TIMSK = 0)
271 #define TIMER_ENABLE_INTR (TIMSK1 = _BV(OCIE1A))
272 #define TIMER_DISABLE_INTR (TIMSK1 = 0)
274 #define TIMER_INTR_NAME TIMER1_COMPA_vect
275 #define TIMER_CONFIG_KHZ(val) ({ \
276 const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
277 TCCR1A = _BV(WGM11); \
278 TCCR1B = _BV(WGM13) | _BV(CS10); \
280 OCR1A = pwmval / 3; \
282 #define TIMER_CONFIG_NORMAL() ({ \
284 TCCR1B = _BV(WGM12) | _BV(CS10); \
285 OCR1A = SYSCLOCK * USECPERTICK / 1000000; \
288 #if defined(CORE_OC1A_PIN)
289 #define TIMER_PWM_PIN CORE_OC1A_PIN /* Teensy */
290 #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
291 #define TIMER_PWM_PIN 11 /* Arduino Mega */
292 #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
293 #define TIMER_PWM_PIN 13 /* Sanguino */
295 #define TIMER_PWM_PIN 9 /* Arduino Duemilanove, Diecimila, LilyPad, etc */
299 // defines for timer3 (16 bits)
300 #elif defined(IR_USE_TIMER3)
302 #define TIMER_ENABLE_PWM (TCCR3A |= _BV(COM3A1))
303 #define TIMER_DISABLE_PWM (TCCR3A &= ~(_BV(COM3A1)))
304 #define TIMER_ENABLE_INTR (TIMSK3 = _BV(OCIE3A))
305 #define TIMER_DISABLE_INTR (TIMSK3 = 0)
306 #define TIMER_INTR_NAME TIMER3_COMPA_vect
307 #define TIMER_CONFIG_KHZ(val) ({ \
308 const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
309 TCCR3A = _BV(WGM31); \
310 TCCR3B = _BV(WGM33) | _BV(CS30); \
312 OCR3A = pwmval / 3; \
314 #define TIMER_CONFIG_NORMAL() ({ \
316 TCCR3B = _BV(WGM32) | _BV(CS30); \
317 OCR3A = SYSCLOCK * USECPERTICK / 1000000; \
320 #if defined(CORE_OC3A_PIN)
321 #define TIMER_PWM_PIN CORE_OC3A_PIN /* Teensy */
322 #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
323 #define TIMER_PWM_PIN 5 /* Arduino Mega */
325 #error "Please add OC3A pin number here\n"
329 // defines for timer4 (10 bits, high speed option)
330 #elif defined(IR_USE_TIMER4_HS)
332 #define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1))
333 #define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1)))
334 #define TIMER_ENABLE_INTR (TIMSK4 = _BV(TOIE4))
335 #define TIMER_DISABLE_INTR (TIMSK4 = 0)
336 #define TIMER_INTR_NAME TIMER4_OVF_vect
337 #define TIMER_CONFIG_KHZ(val) ({ \
338 const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
339 TCCR4A = (1<<PWM4A); \
340 TCCR4B = _BV(CS40); \
342 TCCR4D = (1<<WGM40); \
344 TC4H = pwmval >> 8; \
346 TC4H = (pwmval / 3) >> 8; \
347 OCR4A = (pwmval / 3) & 255; \
349 #define TIMER_CONFIG_NORMAL() ({ \
351 TCCR4B = _BV(CS40); \
355 TC4H = (SYSCLOCK * USECPERTICK / 1000000) >> 8; \
356 OCR4C = (SYSCLOCK * USECPERTICK / 1000000) & 255; \
360 #if defined(CORE_OC4A_PIN)
361 #define TIMER_PWM_PIN CORE_OC4A_PIN /* Teensy */
362 #elif defined(__AVR_ATmega32U4__)
363 #define TIMER_PWM_PIN 13 /* Leonardo */
365 #error "Please add OC4A pin number here\n"
369 // defines for timer4 (16 bits)
370 #elif defined(IR_USE_TIMER4)
372 #define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1))
373 #define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1)))
374 #define TIMER_ENABLE_INTR (TIMSK4 = _BV(OCIE4A))
375 #define TIMER_DISABLE_INTR (TIMSK4 = 0)
376 #define TIMER_INTR_NAME TIMER4_COMPA_vect
377 #define TIMER_CONFIG_KHZ(val) ({ \
378 const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
379 TCCR4A = _BV(WGM41); \
380 TCCR4B = _BV(WGM43) | _BV(CS40); \
382 OCR4A = pwmval / 3; \
384 #define TIMER_CONFIG_NORMAL() ({ \
386 TCCR4B = _BV(WGM42) | _BV(CS40); \
387 OCR4A = SYSCLOCK * USECPERTICK / 1000000; \
390 #if defined(CORE_OC4A_PIN)
391 #define TIMER_PWM_PIN CORE_OC4A_PIN
392 #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
393 #define TIMER_PWM_PIN 6 /* Arduino Mega */
395 #error "Please add OC4A pin number here\n"
399 // defines for timer5 (16 bits)
400 #elif defined(IR_USE_TIMER5)
402 #define TIMER_ENABLE_PWM (TCCR5A |= _BV(COM5A1))
403 #define TIMER_DISABLE_PWM (TCCR5A &= ~(_BV(COM5A1)))
404 #define TIMER_ENABLE_INTR (TIMSK5 = _BV(OCIE5A))
405 #define TIMER_DISABLE_INTR (TIMSK5 = 0)
406 #define TIMER_INTR_NAME TIMER5_COMPA_vect
407 #define TIMER_CONFIG_KHZ(val) ({ \
408 const uint16_t pwmval = SYSCLOCK / 2000 / (val); \
409 TCCR5A = _BV(WGM51); \
410 TCCR5B = _BV(WGM53) | _BV(CS50); \
412 OCR5A = pwmval / 3; \
414 #define TIMER_CONFIG_NORMAL() ({ \
416 TCCR5B = _BV(WGM52) | _BV(CS50); \
417 OCR5A = SYSCLOCK * USECPERTICK / 1000000; \
420 #if defined(CORE_OC5A_PIN)
421 #define TIMER_PWM_PIN CORE_OC5A_PIN
422 #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
423 #define TIMER_PWM_PIN 46 /* Arduino Mega */
425 #error "Please add OC5A pin number here\n"
429 #else // unknown timer
430 #error "Internal code configuration error, no known IR_USE_TIMER# defined\n"
434 // defines for blinking the LED
435 #if defined(CORE_LED0_PIN)
436 #define BLINKLED CORE_LED0_PIN
437 #define BLINKLED_ON() (digitalWrite(CORE_LED0_PIN, HIGH))
438 #define BLINKLED_OFF() (digitalWrite(CORE_LED0_PIN, LOW))
439 #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
441 #define BLINKLED_ON() (PORTB |= B10000000)
442 #define BLINKLED_OFF() (PORTB &= B01111111)
443 #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
445 #define BLINKLED_ON() (PORTD |= B00000001)
446 #define BLINKLED_OFF() (PORTD &= B11111110)
449 #define BLINKLED_ON() (PORTB |= B00100000)
450 #define BLINKLED_OFF() (PORTB &= B11011111)