1 /*---------------------------------------------------------------------------------------------------------------------------------------------------
2 * irmp.c - infrared multi-protocol decoder, supports several remote control protocols
4 * Copyright (c) 2009-2010 Frank Meyer - frank(at)fli4l.de
8 * Typical manufacturers:
11 * NEC - NEC, Yamaha, Canon, Tevion, Harman/Kardon, Hitachi, JVC, Pioneer, Toshiba, Xoro, Orion, and many other Japanese manufacturers
13 * MATSUSHITA - Matsushita
14 * KASEIKYO - Panasonic, Denon & other Japanese manufacturers (members of "Japan's Association for Electric Home Application")
15 * RECS80 - Philips, Nokia, Thomson, Nordmende, Telefunken, Saba
16 * RC5 - Philips and other European manufacturers
18 * RC6 - Philips and other European manufacturers
20 * NUBERT - Nubert Subwoofer System
21 * PANASONIC - Panasonic (older, yet not implemented)
23 *---------------------------------------------------------------------------------------------------------------------------------------------------
28 * frame: 1 start bit + 12-20 data bits + no stop bit
29 * data: 7 command bits + 5 address bits + 0 to 8 additional bits
31 * start bit: data "0": data "1": stop bit:
32 * -----------------_________ ------_____ ------------______
33 * 2400us 600us 600us 600us 1200us 600 us no stop bit
35 *---------------------------------------------------------------------------------------------------------------------------------------------------
38 * -------------------------
40 * frame: 1 start bit + 32 data bits + 1 stop bit
41 * data NEC: 8 address bits + 8 inverted address bits + 8 command bits + 8 inverted command bits
42 * data extended NEC: 16 address bits + 8 command bits + 8 inverted command bits
44 * start bit: data "0": data "1": stop bit:
45 * -----------------_________ ------______ ------________________ ------______....
46 * 9000us 4500us 560us 560us 560us 1690 us 560us
51 * -----------------_________------______ .... ~100ms Pause, then repeat
54 *---------------------------------------------------------------------------------------------------------------------------------------------------
59 * frame: 1 start bit + 16 data(1) bits + 1 sync bit + additional 20 data(2) bits + 1 stop bit
60 * data(1): 16 address bits
61 * data(2): 4 ID bits + 8 command bits + 8 inverted command bits
63 * start bit: data "0": data "1": sync bit: stop bit:
64 * ----------______________ ------______ ------________________ ------______________ ------______....
65 * 4500us 4500us 550us 450us 550us 1450us 550us 4500us 550us
67 *---------------------------------------------------------------------------------------------------------------------------------------------------
72 * frame: 1 start bit + 32 data bits + 1 stop bit
73 * data: 16 address bits + 16 command bits
75 * start bit: data "0": data "1": stop bit:
76 * ----------______________ ------______ ------________________ ------______....
77 * 4500us 4500us 550us 450us 550us 1450us 550us
79 *---------------------------------------------------------------------------------------------------------------------------------------------------
84 * frame: 1 start bit + 24 data bits + 1 stop bit
85 * data: 6 custom bits + 6 command bits + 12 address bits
87 * start bit: data "0": data "1": stop bit:
88 * ----------_________ ------______ ------________________ ------______....
89 * 3488us 3488us 872us 872us 872us 2616us 872us
91 *---------------------------------------------------------------------------------------------------------------------------------------------------
96 * frame: 1 start bit + 48 data bits + 1 stop bit
97 * data: 16 manufacturer bits + 4 parity bits + 4 genre1 bits + 4 genre2 bits + 10 command bits + 2 id bits + 8 parity bits
99 * start bit: data "0": data "1": stop bit:
100 * ----------______ ------______ ------________________ ------______....
101 * 3380us 1690us 423us 423us 423us 1269us 423us
103 *---------------------------------------------------------------------------------------------------------------------------------------------------
108 * frame: 2 start bits + 10 data bits + 1 stop bit
109 * data: 1 toggle bit + 3 address bits + 6 command bits
111 * start bit: data "0": data "1": stop bit:
112 * -----_____________________ -----____________ -----______________ ------_______....
113 * 158us 7432us 158us 4902us 158us 7432us 158us
115 *---------------------------------------------------------------------------------------------------------------------------------------------------
120 * frame: 2 start bits + 11 data bits + 1 stop bit
121 * data: 1 toggle bit + 4 address bits + 6 command bits
123 * start bit: data "0": data "1": stop bit:
124 * -----_____________________ -----____________ -----______________ ------_______....
125 * 158us 3637us 158us 4902us 158us 7432us 158us
127 *---------------------------------------------------------------------------------------------------------------------------------------------------
132 * RC5 frame: 2 start bits + 12 data bits + no stop bit
133 * RC5 data: 1 toggle bit + 5 address bits + 6 command bits
134 * RC5X frame: 1 start bit + 13 data bits + no stop bit
135 * RC5X data: 1 inverted command bit + 1 toggle bit + 5 address bits + 6 command bits
137 * start bit: data "0": data "1":
138 * ______----- ------______ ______------
139 * 889us 889us 889us 889us 889us 889us
141 *---------------------------------------------------------------------------------------------------------------------------------------------------
146 * frame: 0 start bits + 16 data bits + stop bit + 65ms pause + 16 inverted data bits + stop bit
147 * data: 5 address bits + 10 command bits
149 * data "0": data "1":
150 * ------________________ ------______________
151 * 275us 1050us 275us 1900us
153 *---------------------------------------------------------------------------------------------------------------------------------------------------
158 * RC6 frame: 1 start bit + 1 bit "1" + 3 mode bits + 1 toggle bit + 16 data bits + 2666 µs pause
159 * RC6 data: 8 address bits + 8 command bits
161 * start bit toggle bit "0": toggle bit "1": data/mode "0": data/mode "1":
162 * ____________------- _______------- -------_______ _______------- -------_______
163 * 2666us 889us 889us 889us 889us 889us 444us 444us 444us 444us
165 *---------------------------------------------------------------------------------------------------------------------------------------------------
170 * frame: 1 start bit + 32 data bits + 1 stop bit
171 * data: 16 address bits + 11100000 + 8 command bits
173 * start bit: data "0": data "1": stop bit:
174 * -----------------_________ ------______ ------________________ ------______....
175 * 9000us 4500us 560us 560us 560us 1690 us 560us
177 *---------------------------------------------------------------------------------------------------------------------------------------------------
179 * NUBERT (subwoofer system)
180 * -------------------------
182 * frame: 1 start bit + 10 data bits + 1 stop bit
183 * data: 0 address bits + 10 command bits ?
185 * start bit: data "0": data "1": stop bit:
186 * ----------_____ ------______ ------________________ ------______....
187 * 1340us 340us 500us 1300us 1340us 340us 500us
189 *---------------------------------------------------------------------------------------------------------------------------------------------------
191 * PANASONIC (older protocol, yet not implemented, see also MATSUSHITA, timing very similar)
192 * -----------------------------------------------------------------------------------------
194 * frame: 1 start bit + 22 data bits + 1 stop bit
195 * 22 data bits = 5 custom bits + 6 data bits + 5 inverted custom bits + 6 inverted data bits
197 * European version: T = 456us
198 * USA & Canada version: T = 422us
200 * start bit: data "0": data "1": stop bit:
201 * 8T 8T 2T 2T 2T 6T 2T
202 * -------------____________ ------_____ ------_____________ ------_______....
203 * 3648us 3648us 912us 912us 912us 2736us 912us (Europe)
204 * 3376us 3376us 844us 844us 844us 2532us 844us (US)
206 *---------------------------------------------------------------------------------------------------------------------------------------------------
208 * This program is free software; you can redistribute it and/or modify
209 * it under the terms of the GNU General Public License as published by
210 * the Free Software Foundation; either version 2 of the License, or
211 * (at your option) any later version.
212 *---------------------------------------------------------------------------------------------------------------------------------------------------
215 #if defined(__PCM__) || defined(__PCB__) || defined(__PCH__) // CCS PIC Compiler instead of AVR
216 #define PIC_CCS_COMPILER
219 #ifdef unix // test on linux/unix
224 #include <inttypes.h>
228 #define memcpy_P memcpy
235 typedef unsigned char uint8_t;
236 typedef unsigned short uint16_t;
239 #define memcpy_P memcpy
245 #ifdef PIC_CCS_COMPILER
248 typedef unsigned int8
uint8_t;
249 typedef unsigned int16
uint16_t;
251 #define memcpy_P memcpy
255 #include <inttypes.h>
259 #include <util/delay.h>
260 #include <avr/pgmspace.h>
262 #endif // PIC_CCS_COMPILER
270 /*---------------------------------------------------------------------------------------------------------------------------------------------------
271 * Change settings from 1 to 0 if you want to disable one or more decoders.
272 * This saves program space.
275 *---------------------------------------------------------------------------------------------------------------------------------------------------
277 #define IRMP_SUPPORT_SIRCS_PROTOCOL 1 // flag: support SIRCS uses ~100 bytes
278 #define IRMP_SUPPORT_NEC_PROTOCOL 1 // flag: support NEC + APPLE uses ~250 bytes
279 #define IRMP_SUPPORT_SAMSUNG_PROTOCOL 1 // flag: support Samsung + Samsung32 uses ~250 bytes
280 #define IRMP_SUPPORT_MATSUSHITA_PROTOCOL 1 // flag: support Matsushita uses ~50 bytes
281 #define IRMP_SUPPORT_KASEIKYO_PROTOCOL 1 // flag: support Kaseikyo uses ~50 bytes
282 #define IRMP_SUPPORT_RECS80_PROTOCOL 1 // flag: support RECS80 uses ~50 bytes
283 #define IRMP_SUPPORT_RC5_PROTOCOL 1 // flag: support RC5 uses ~250 bytes
284 #define IRMP_SUPPORT_DENON_PROTOCOL 1 // flag: support DENON uses ~250 bytes
285 #define IRMP_SUPPORT_RC6_PROTOCOL 1 // flag: support RC6 uses ~200 bytes
286 #define IRMP_SUPPORT_RECS80EXT_PROTOCOL 1 // flag: support RECS80EXT uses ~50 bytes
287 #define IRMP_SUPPORT_NUBERT_PROTOCOL 1 // flag: support NUBERT uses ~50 bytes
289 /*---------------------------------------------------------------------------------------------------------------------------------------------------
290 * Change hardware pin here:
291 *---------------------------------------------------------------------------------------------------------------------------------------------------
293 #ifdef PIC_CCS_COMPILER // PIC CCS Compiler:
295 #define IRMP_PIN PIN_B4 // use PB4 as IR input on PIC
299 #define IRMP_PORT PORTB
300 #define IRMP_DDR DDRB
301 #define IRMP_PIN PINB
302 #define IRMP_BIT 6 // use PB6 as IR input on AVR
304 #define input(x) ((x) & (1 << IRMP_BIT))
307 /*---------------------------------------------------------------------------------------------------------------------------------------------------
308 * Set IRMP_LOGGING to 1 if want to log data to UART with 9600Bd
309 *---------------------------------------------------------------------------------------------------------------------------------------------------
311 #define IRMP_LOGGING 0 // 1: log IR signal (scan), 0: do not (default)
313 #define IRMP_TIMEOUT 120 // timeout after 12 ms darkness
314 #define IRMP_REPETITION_TIME (uint16_t)(F_INTERRUPTS * 100.0e-3 + 0.5) // autodetect key repetition within 100 msec
316 #define MIN_TOLERANCE_10 0.9 // -10%
317 #define MAX_TOLERANCE_10 1.1 // +10%
319 #define MIN_TOLERANCE_20 0.8 // -20%
320 #define MAX_TOLERANCE_20 1.2 // +20%
322 #define MIN_TOLERANCE_30 0.7 // -30%
323 #define MAX_TOLERANCE_30 1.3 // +30%
325 #define MIN_TOLERANCE_40 0.6 // -40%
326 #define MAX_TOLERANCE_40 1.4 // +40%
328 #define MIN_TOLERANCE_50 0.5 // -50%
329 #define MAX_TOLERANCE_50 1.5 // +50%
331 #define MIN_TOLERANCE_60 0.4 // -60%
332 #define MAX_TOLERANCE_60 1.6 // +60%
334 #define SIRCS_START_BIT_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * SIRCS_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5)
335 #define SIRCS_START_BIT_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * SIRCS_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5)
336 #define SIRCS_START_BIT_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * SIRCS_START_BIT_PAUSE_TIME * MIN_TOLERANCE_50 + 0.5)
337 #define SIRCS_START_BIT_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * SIRCS_START_BIT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5)
338 #define SIRCS_1_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * SIRCS_1_PULSE_TIME * MIN_TOLERANCE_20 + 0.5)
339 #define SIRCS_1_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * SIRCS_1_PULSE_TIME * MAX_TOLERANCE_30 + 0.5)
340 #define SIRCS_0_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * SIRCS_0_PULSE_TIME * MIN_TOLERANCE_50 + 0.5)
341 #define SIRCS_0_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * SIRCS_0_PULSE_TIME * MAX_TOLERANCE_50 + 0.5)
342 #define SIRCS_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * SIRCS_PAUSE_TIME * MIN_TOLERANCE_50 + 0.5)
343 #define SIRCS_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * SIRCS_PAUSE_TIME * MAX_TOLERANCE_50 + 0.5)
345 #define NEC_START_BIT_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * NEC_START_BIT_PULSE_TIME * MIN_TOLERANCE_40 + 0.5)
346 #define NEC_START_BIT_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * NEC_START_BIT_PULSE_TIME * MAX_TOLERANCE_40 + 0.5)
347 #define NEC_START_BIT_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * NEC_START_BIT_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5)
348 #define NEC_START_BIT_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * NEC_START_BIT_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5)
349 #define NEC_REPEAT_START_BIT_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * NEC_REPEAT_START_BIT_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5)
350 #define NEC_REPEAT_START_BIT_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * NEC_REPEAT_START_BIT_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5)
351 #define NEC_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * NEC_PULSE_TIME * MIN_TOLERANCE_40 + 0.5)
352 #define NEC_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * NEC_PULSE_TIME * MAX_TOLERANCE_40 + 0.5)
353 #define NEC_1_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * NEC_1_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5)
354 #define NEC_1_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * NEC_1_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5)
355 #define NEC_0_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * NEC_0_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5)
356 #define NEC_0_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * NEC_0_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5)
358 #define SAMSUNG_START_BIT_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5)
359 #define SAMSUNG_START_BIT_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5)
360 #define SAMSUNG_START_BIT_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5)
361 #define SAMSUNG_START_BIT_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5)
362 #define SAMSUNG_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * SAMSUNG_PULSE_TIME * MIN_TOLERANCE_50 + 0.5)
363 #define SAMSUNG_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * SAMSUNG_PULSE_TIME * MAX_TOLERANCE_50 + 0.5)
364 #define SAMSUNG_1_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * SAMSUNG_1_PAUSE_TIME * MIN_TOLERANCE_50 + 0.5)
365 #define SAMSUNG_1_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * SAMSUNG_1_PAUSE_TIME * MAX_TOLERANCE_50 + 0.5)
366 #define SAMSUNG_0_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * SAMSUNG_0_PAUSE_TIME * MIN_TOLERANCE_50 + 0.5)
367 #define SAMSUNG_0_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * SAMSUNG_0_PAUSE_TIME * MAX_TOLERANCE_50 + 0.5)
369 #define MATSUSHITA_START_BIT_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5)
370 #define MATSUSHITA_START_BIT_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5)
371 #define MATSUSHITA_START_BIT_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5)
372 #define MATSUSHITA_START_BIT_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5)
373 #define MATSUSHITA_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * MATSUSHITA_PULSE_TIME * MIN_TOLERANCE_40 + 0.5)
374 #define MATSUSHITA_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * MATSUSHITA_PULSE_TIME * MAX_TOLERANCE_40 + 0.5)
375 #define MATSUSHITA_1_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * MATSUSHITA_1_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5)
376 #define MATSUSHITA_1_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * MATSUSHITA_1_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5)
377 #define MATSUSHITA_0_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * MATSUSHITA_0_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5)
378 #define MATSUSHITA_0_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * MATSUSHITA_0_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5)
380 #define KASEIKYO_START_BIT_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PULSE_TIME * MIN_TOLERANCE_30 + 0.5)
381 #define KASEIKYO_START_BIT_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PULSE_TIME * MAX_TOLERANCE_30 + 0.5)
382 #define KASEIKYO_START_BIT_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5)
383 #define KASEIKYO_START_BIT_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5)
384 #define KASEIKYO_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * KASEIKYO_PULSE_TIME * MIN_TOLERANCE_50 + 0.5)
385 #define KASEIKYO_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * KASEIKYO_PULSE_TIME * MAX_TOLERANCE_60 + 0.5)
386 #define KASEIKYO_1_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * KASEIKYO_1_PAUSE_TIME * MIN_TOLERANCE_50 + 0.5)
387 #define KASEIKYO_1_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * KASEIKYO_1_PAUSE_TIME * MAX_TOLERANCE_50 + 0.5)
388 #define KASEIKYO_0_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * KASEIKYO_0_PAUSE_TIME * MIN_TOLERANCE_50 + 0.5)
389 #define KASEIKYO_0_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * KASEIKYO_0_PAUSE_TIME * MAX_TOLERANCE_50 + 0.5)
391 #define RECS80_START_BIT_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * RECS80_START_BIT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5)
392 #define RECS80_START_BIT_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * RECS80_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5)
393 #define RECS80_START_BIT_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * RECS80_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5)
394 #define RECS80_START_BIT_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * RECS80_START_BIT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5)
395 #define RECS80_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * RECS80_PULSE_TIME * MIN_TOLERANCE_20 + 0.5)
396 #define RECS80_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * RECS80_PULSE_TIME * MAX_TOLERANCE_20 + 0.5)
397 #define RECS80_1_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * RECS80_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5)
398 #define RECS80_1_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * RECS80_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5)
399 #define RECS80_0_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * RECS80_0_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5)
400 #define RECS80_0_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * RECS80_0_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5)
402 #define RC5_START_BIT_LEN_MIN (uint8_t)(F_INTERRUPTS * RC5_BIT_TIME * MIN_TOLERANCE_20 + 0.5)
403 #define RC5_START_BIT_LEN_MAX (uint8_t)(F_INTERRUPTS * RC5_BIT_TIME * MAX_TOLERANCE_20 + 0.5)
404 #define RC5_BIT_LEN_MIN (uint8_t)(F_INTERRUPTS * RC5_BIT_TIME * MIN_TOLERANCE_20 + 0.5)
405 #define RC5_BIT_LEN_MAX (uint8_t)(F_INTERRUPTS * RC5_BIT_TIME * MAX_TOLERANCE_20 + 0.5)
407 #define DENON_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * DENON_PULSE_TIME * MIN_TOLERANCE_50 + 0.5)
408 #define DENON_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * DENON_PULSE_TIME * MAX_TOLERANCE_50 + 0.5)
409 #define DENON_1_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * DENON_1_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5)
410 #define DENON_1_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * DENON_1_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5)
411 #define DENON_0_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * DENON_0_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5)
412 #define DENON_0_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * DENON_0_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5)
414 #define RC6_START_BIT_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * RC6_START_BIT_PULSE_TIME * MIN_TOLERANCE_30 + 0.5)
415 #define RC6_START_BIT_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * RC6_START_BIT_PULSE_TIME * MAX_TOLERANCE_30 + 0.5)
416 #define RC6_START_BIT_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * RC6_START_BIT_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5)
417 #define RC6_START_BIT_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * RC6_START_BIT_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5)
418 #define RC6_TOGGLE_BIT_LEN_MIN (uint8_t)(F_INTERRUPTS * RC6_TOGGLE_BIT_TIME * MIN_TOLERANCE_20 + 0.5)
419 #define RC6_TOGGLE_BIT_LEN_MAX (uint8_t)(F_INTERRUPTS * RC6_TOGGLE_BIT_TIME * MAX_TOLERANCE_20 + 0.5)
420 #define RC6_BIT_LEN_MIN (uint8_t)(F_INTERRUPTS * RC6_BIT_TIME * MIN_TOLERANCE_30 + 0.5)
421 #define RC6_BIT_LEN_MAX (uint8_t)(F_INTERRUPTS * RC6_BIT_TIME * MAX_TOLERANCE_30 + 0.5)
423 #define RECS80EXT_START_BIT_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5)
424 #define RECS80EXT_START_BIT_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5)
425 #define RECS80EXT_START_BIT_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5)
426 #define RECS80EXT_START_BIT_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5)
427 #define RECS80EXT_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * RECS80EXT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5)
428 #define RECS80EXT_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * RECS80EXT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5)
429 #define RECS80EXT_1_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * RECS80EXT_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5)
430 #define RECS80EXT_1_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * RECS80EXT_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5)
431 #define RECS80EXT_0_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * RECS80EXT_0_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5)
432 #define RECS80EXT_0_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * RECS80EXT_0_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5)
434 #define NUBERT_START_BIT_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * NUBERT_START_BIT_PULSE_TIME * MIN_TOLERANCE_40 + 0.5)
435 #define NUBERT_START_BIT_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * NUBERT_START_BIT_PULSE_TIME * MAX_TOLERANCE_40 + 0.5)
436 #define NUBERT_START_BIT_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * NUBERT_START_BIT_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5)
437 #define NUBERT_START_BIT_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * NUBERT_START_BIT_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5)
438 #define NUBERT_1_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * NUBERT_1_PULSE_TIME * MIN_TOLERANCE_40 + 0.5)
439 #define NUBERT_1_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * NUBERT_1_PULSE_TIME * MAX_TOLERANCE_40 + 0.5)
440 #define NUBERT_1_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * NUBERT_1_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5)
441 #define NUBERT_1_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * NUBERT_1_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5)
442 #define NUBERT_0_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * NUBERT_0_PULSE_TIME * MIN_TOLERANCE_40 + 0.5)
443 #define NUBERT_0_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * NUBERT_0_PULSE_TIME * MAX_TOLERANCE_40 + 0.5)
444 #define NUBERT_0_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * NUBERT_0_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5)
445 #define NUBERT_0_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * NUBERT_0_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5)
447 #define AUTO_REPETITION_LEN (uint16_t)(F_INTERRUPTS * AUTO_REPETITION_TIME + 0.5) // use uint16_t!
450 #define DEBUG_PUTCHAR(a) { if (! silent) { putchar (a); } }
451 #define DEBUG_PRINTF(...) { if (! silent) { printf (__VA_ARGS__); } }
454 #define DEBUG_PUTCHAR(a)
455 #define DEBUG_PRINTF(...)
458 #if IRMP_LOGGING == 1
459 #define irmp_logIsr(x) irmp_logIr((x) ? 1:0)
460 #define UART_BAUD 9600L
462 // calculate real baud rate:
463 #define UBRR_VAL ((F_CPU+UART_BAUD*8)/(UART_BAUD*16)-1) // round
464 #define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) // real baudrate
467 #if ((BAUD_REAL*1000)/UART_BAUD-1000) > 10
468 # error Error of baud rate of RS232 UARTx is more than 1%. That is too high!
471 #else // not CODEVISION
473 #define BAUD_ERROR ((BAUD_REAL*1000)/UART_BAUD-1000) // error in promille
475 #if ((BAUD_ERROR > 10) || (-BAUD_ERROR < 10))
476 # error Error of baud rate of RS232 UARTx is more than 1%. That is too high!
481 /*---------------------------------------------------------------------------------------------------------------------------------------------------
483 * @details Initializes UART
484 *---------------------------------------------------------------------------------------------------------------------------------------------------
487 irmp_uart_init (void)
489 UCSR0B
|= (1<<TXEN0
); // activate UART0 TX
490 UBRR0H
= UBRR_VAL
>> 8; // store baudrate (upper byte)
491 UBRR0L
= UBRR_VAL
& 0xFF; // store baudrate (lower byte)
494 /*---------------------------------------------------------------------------------------------------------------------------------------------------
496 * @details Sends character
497 * @param ch character to be transmitted
498 *---------------------------------------------------------------------------------------------------------------------------------------------------
501 irmp_uart_putc (unsigned char ch
)
503 while (!(UCSR0A
& (1<<UDRE0
)))
511 /*---------------------------------------------------------------------------------------------------------------------------------------------------
513 *---------------------------------------------------------------------------------------------------------------------------------------------------
515 #define c_startcycles 2 // min count of zeros before start of logging
516 #define c_endBits 1000 // log buffer size
517 #define c_datalen 700 // number of sequenced highbits to detect end
520 irmp_logIr (uint8_t val
)
522 static uint8_t s_data
[c_datalen
]; // logging buffer
523 static uint16_t s_dataIdx
; // number of written bits
524 static uint8_t s_startcycles
; // current number of start-zeros
525 static uint16_t s_ctr
; // counts sequenced highbits - to detect end
527 if ((val
== 0) && (s_startcycles
< c_startcycles
) && !s_dataIdx
) // prevent that single random zeros init logging
535 if ( (val
== 0) // start or continue logging on "0"
536 || ((val
== 1) && (s_dataIdx
!= 0))) // "1" cannot init logging
539 { // set or clear bit in bitarray
540 s_data
[(s_dataIdx
/ 8)] |= (1<<(s_dataIdx
% 8));
544 s_data
[(s_dataIdx
/ 8)] &= ~(1<<(s_dataIdx
% 8));
550 { // if high received then look at log-stop condition
553 if (s_ctr
> c_endBits
)
554 { // if stop condition (200 sequenced ones) meets, output on uart
557 for (i
= 0; i
< c_startcycles
; ++i
)
559 irmp_uart_putc ('0'); // the ignored starting zeros
562 for (i
= 0;i
< (s_dataIdx
- c_endBits
+ 20) / 8; ++i
) // transform bitset into uart chars
564 uint8_t d
= s_data
[i
];
569 irmp_uart_putc ((d
& 1) + '0');
574 irmp_uart_putc ('\n');
587 #define irmp_logIsr(x)
592 uint8_t protocol
; // ir protocol
593 uint8_t pulse_1_len_min
; // minimum length of pulse with bit value 1
594 uint8_t pulse_1_len_max
; // maximum length of pulse with bit value 1
595 uint8_t pause_1_len_min
; // minimum length of pause with bit value 1
596 uint8_t pause_1_len_max
; // maximum length of pause with bit value 1
597 uint8_t pulse_0_len_min
; // minimum length of pulse with bit value 0
598 uint8_t pulse_0_len_max
; // maximum length of pulse with bit value 0
599 uint8_t pause_0_len_min
; // minimum length of pause with bit value 0
600 uint8_t pause_0_len_max
; // maximum length of pause with bit value 0
601 uint8_t address_offset
; // address offset
602 uint8_t address_end
; // end of address
603 uint8_t command_offset
; // command offset
604 uint8_t command_end
; // end of command
605 uint8_t complete_len
; // complete length of frame
606 uint8_t stop_bit
; // flag: frame has stop bit
607 uint8_t lsb_first
; // flag: LSB first
610 #if IRMP_SUPPORT_SIRCS_PROTOCOL == 1
612 static PROGMEM IRMP_PARAMETER sircs_param
=
615 SIRCS_1_PULSE_LEN_MIN
,
616 SIRCS_1_PULSE_LEN_MAX
,
619 SIRCS_0_PULSE_LEN_MIN
,
620 SIRCS_0_PULSE_LEN_MAX
,
623 SIRCS_ADDRESS_OFFSET
,
624 SIRCS_ADDRESS_OFFSET
+ SIRCS_ADDRESS_LEN
,
625 SIRCS_COMMAND_OFFSET
,
626 SIRCS_COMMAND_OFFSET
+ SIRCS_COMMAND_LEN
,
627 SIRCS_COMPLETE_DATA_LEN
,
634 #if IRMP_SUPPORT_NEC_PROTOCOL == 1
636 static PROGMEM IRMP_PARAMETER nec_param
=
648 NEC_ADDRESS_OFFSET
+ NEC_ADDRESS_LEN
,
650 NEC_COMMAND_OFFSET
+ NEC_COMMAND_LEN
,
651 NEC_COMPLETE_DATA_LEN
,
658 #if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1
660 static PROGMEM IRMP_PARAMETER samsung_param
=
662 IRMP_SAMSUNG_PROTOCOL
,
663 SAMSUNG_PULSE_LEN_MIN
,
664 SAMSUNG_PULSE_LEN_MAX
,
665 SAMSUNG_1_PAUSE_LEN_MIN
,
666 SAMSUNG_1_PAUSE_LEN_MAX
,
667 SAMSUNG_PULSE_LEN_MIN
,
668 SAMSUNG_PULSE_LEN_MAX
,
669 SAMSUNG_0_PAUSE_LEN_MIN
,
670 SAMSUNG_0_PAUSE_LEN_MAX
,
671 SAMSUNG_ADDRESS_OFFSET
,
672 SAMSUNG_ADDRESS_OFFSET
+ SAMSUNG_ADDRESS_LEN
,
673 SAMSUNG_COMMAND_OFFSET
,
674 SAMSUNG_COMMAND_OFFSET
+ SAMSUNG_COMMAND_LEN
,
675 SAMSUNG_COMPLETE_DATA_LEN
,
682 #if IRMP_SUPPORT_MATSUSHITA_PROTOCOL == 1
684 static PROGMEM IRMP_PARAMETER matsushita_param
=
686 IRMP_MATSUSHITA_PROTOCOL
,
687 MATSUSHITA_PULSE_LEN_MIN
,
688 MATSUSHITA_PULSE_LEN_MAX
,
689 MATSUSHITA_1_PAUSE_LEN_MIN
,
690 MATSUSHITA_1_PAUSE_LEN_MAX
,
691 MATSUSHITA_PULSE_LEN_MIN
,
692 MATSUSHITA_PULSE_LEN_MAX
,
693 MATSUSHITA_0_PAUSE_LEN_MIN
,
694 MATSUSHITA_0_PAUSE_LEN_MAX
,
695 MATSUSHITA_ADDRESS_OFFSET
,
696 MATSUSHITA_ADDRESS_OFFSET
+ MATSUSHITA_ADDRESS_LEN
,
697 MATSUSHITA_COMMAND_OFFSET
,
698 MATSUSHITA_COMMAND_OFFSET
+ MATSUSHITA_COMMAND_LEN
,
699 MATSUSHITA_COMPLETE_DATA_LEN
,
706 #if IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1
708 static PROGMEM IRMP_PARAMETER kaseikyo_param
=
710 IRMP_KASEIKYO_PROTOCOL
,
711 KASEIKYO_PULSE_LEN_MIN
,
712 KASEIKYO_PULSE_LEN_MAX
,
713 KASEIKYO_1_PAUSE_LEN_MIN
,
714 KASEIKYO_1_PAUSE_LEN_MAX
,
715 KASEIKYO_PULSE_LEN_MIN
,
716 KASEIKYO_PULSE_LEN_MAX
,
717 KASEIKYO_0_PAUSE_LEN_MIN
,
718 KASEIKYO_0_PAUSE_LEN_MAX
,
719 KASEIKYO_ADDRESS_OFFSET
,
720 KASEIKYO_ADDRESS_OFFSET
+ KASEIKYO_ADDRESS_LEN
,
721 KASEIKYO_COMMAND_OFFSET
,
722 KASEIKYO_COMMAND_OFFSET
+ KASEIKYO_COMMAND_LEN
,
723 KASEIKYO_COMPLETE_DATA_LEN
,
730 #if IRMP_SUPPORT_RECS80_PROTOCOL == 1
732 static PROGMEM IRMP_PARAMETER recs80_param
=
734 IRMP_RECS80_PROTOCOL
,
735 RECS80_PULSE_LEN_MIN
,
736 RECS80_PULSE_LEN_MAX
,
737 RECS80_1_PAUSE_LEN_MIN
,
738 RECS80_1_PAUSE_LEN_MAX
,
739 RECS80_PULSE_LEN_MIN
,
740 RECS80_PULSE_LEN_MAX
,
741 RECS80_0_PAUSE_LEN_MIN
,
742 RECS80_0_PAUSE_LEN_MAX
,
743 RECS80_ADDRESS_OFFSET
,
744 RECS80_ADDRESS_OFFSET
+ RECS80_ADDRESS_LEN
,
745 RECS80_COMMAND_OFFSET
,
746 RECS80_COMMAND_OFFSET
+ RECS80_COMMAND_LEN
,
747 RECS80_COMPLETE_DATA_LEN
,
754 #if IRMP_SUPPORT_RC5_PROTOCOL == 1
756 static PROGMEM IRMP_PARAMETER rc5_param
=
763 1, // tricky: use this as stop bit length
768 RC5_ADDRESS_OFFSET
+ RC5_ADDRESS_LEN
,
770 RC5_COMMAND_OFFSET
+ RC5_COMMAND_LEN
,
771 RC5_COMPLETE_DATA_LEN
,
778 #if IRMP_SUPPORT_DENON_PROTOCOL == 1
780 static PROGMEM IRMP_PARAMETER denon_param
=
785 DENON_1_PAUSE_LEN_MIN
,
786 DENON_1_PAUSE_LEN_MAX
,
789 DENON_0_PAUSE_LEN_MIN
,
790 DENON_0_PAUSE_LEN_MAX
,
791 DENON_ADDRESS_OFFSET
,
792 DENON_ADDRESS_OFFSET
+ DENON_ADDRESS_LEN
,
793 DENON_COMMAND_OFFSET
,
794 DENON_COMMAND_OFFSET
+ DENON_COMMAND_LEN
,
795 DENON_COMPLETE_DATA_LEN
,
802 #if IRMP_SUPPORT_RC6_PROTOCOL == 1
804 static PROGMEM IRMP_PARAMETER rc6_param
=
811 1, // tricky: use this as stop bit length
816 RC6_ADDRESS_OFFSET
+ RC6_ADDRESS_LEN
,
818 RC6_COMMAND_OFFSET
+ RC6_COMMAND_LEN
,
819 RC6_COMPLETE_DATA_LEN_SHORT
,
826 #if IRMP_SUPPORT_RECS80EXT_PROTOCOL == 1
828 static PROGMEM IRMP_PARAMETER recs80ext_param
=
830 IRMP_RECS80EXT_PROTOCOL
,
831 RECS80EXT_PULSE_LEN_MIN
,
832 RECS80EXT_PULSE_LEN_MAX
,
833 RECS80EXT_1_PAUSE_LEN_MIN
,
834 RECS80EXT_1_PAUSE_LEN_MAX
,
835 RECS80EXT_PULSE_LEN_MIN
,
836 RECS80EXT_PULSE_LEN_MAX
,
837 RECS80EXT_0_PAUSE_LEN_MIN
,
838 RECS80EXT_0_PAUSE_LEN_MAX
,
839 RECS80EXT_ADDRESS_OFFSET
,
840 RECS80EXT_ADDRESS_OFFSET
+ RECS80EXT_ADDRESS_LEN
,
841 RECS80EXT_COMMAND_OFFSET
,
842 RECS80EXT_COMMAND_OFFSET
+ RECS80EXT_COMMAND_LEN
,
843 RECS80EXT_COMPLETE_DATA_LEN
,
850 #if IRMP_SUPPORT_RECS80EXT_PROTOCOL == 1
852 static PROGMEM IRMP_PARAMETER nubert_param
=
854 IRMP_NUBERT_PROTOCOL
,
855 NUBERT_1_PULSE_LEN_MIN
,
856 NUBERT_1_PULSE_LEN_MAX
,
857 NUBERT_1_PAUSE_LEN_MIN
,
858 NUBERT_1_PAUSE_LEN_MAX
,
859 NUBERT_0_PULSE_LEN_MIN
,
860 NUBERT_0_PULSE_LEN_MAX
,
861 NUBERT_0_PAUSE_LEN_MIN
,
862 NUBERT_0_PAUSE_LEN_MAX
,
863 NUBERT_ADDRESS_OFFSET
,
864 NUBERT_ADDRESS_OFFSET
+ NUBERT_ADDRESS_LEN
,
865 NUBERT_COMMAND_OFFSET
,
866 NUBERT_COMMAND_OFFSET
+ NUBERT_COMMAND_LEN
,
867 NUBERT_COMPLETE_DATA_LEN
,
874 static uint8_t irmp_bit
; // current bit position
875 static IRMP_PARAMETER irmp_param
;
877 static volatile uint8_t irmp_ir_detected
;
878 static volatile uint8_t irmp_protocol
;
879 static volatile uint16_t irmp_address
;
880 static volatile uint16_t irmp_command
;
881 static volatile uint16_t irmp_id
; // only used for SAMSUNG protocol
882 static volatile uint8_t irmp_flags
;
885 static uint8_t IRMP_PIN
;
888 /*---------------------------------------------------------------------------------------------------------------------------------------------------
889 * Initialize IRMP decoder
890 * @details Configures IRMP input pin
891 *---------------------------------------------------------------------------------------------------------------------------------------------------
897 #ifndef PIC_CCS_COMPILER
898 IRMP_PORT
&= ~(1<<IRMP_BIT
); // deactivate pullup
899 IRMP_DDR
&= ~(1<<IRMP_BIT
); // set pin to input
900 #endif // PIC_CCS_COMPILER
902 #if IRMP_LOGGING == 1
907 /*---------------------------------------------------------------------------------------------------------------------------------------------------
909 * @details gets decoded IRMP data
910 * @param pointer in order to store IRMP data
911 * @return TRUE: successful, FALSE: failed
912 *---------------------------------------------------------------------------------------------------------------------------------------------------
915 irmp_get_data (IRMP_DATA
* irmp_data_p
)
919 if (irmp_ir_detected
)
921 switch (irmp_protocol
)
923 #if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1
924 case IRMP_SAMSUNG_PROTOCOL
:
925 if ((irmp_command
>> 8) == (~irmp_command
& 0x00FF))
927 irmp_command
&= 0xff;
928 irmp_command
|= irmp_id
<< 8;
933 #if IRMP_SUPPORT_NEC_PROTOCOL == 1
934 case IRMP_NEC_PROTOCOL
:
935 if ((irmp_command
>> 8) == (~irmp_command
& 0x00FF))
937 irmp_command
&= 0xff;
940 else if ((irmp_command
& 0xFF00) == 0xD100)
942 DEBUG_PRINTF ("Switching to APPLE protocol\n");
943 irmp_protocol
= IRMP_APPLE_PROTOCOL
;
944 irmp_command
&= 0xff;
955 irmp_data_p
->protocol
= irmp_protocol
;
956 irmp_data_p
->address
= irmp_address
;
957 irmp_data_p
->command
= irmp_command
;
958 irmp_data_p
->flags
= irmp_flags
;
964 irmp_ir_detected
= FALSE
;
970 // these statics must not be volatile, because they are only used by irmp_store_bit(), which is called by irmp_ISR()
971 static uint16_t irmp_tmp_address
; // ir address
972 static uint16_t irmp_tmp_command
; // ir command
973 #if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1
974 static uint16_t irmp_tmp_id
; // ir id (only SAMSUNG)
977 static uint8_t irmp_bit
; // current bit position
979 /*---------------------------------------------------------------------------------------------------------------------------------------------------
981 * @details store bit in temp address or temp command
982 * @param value to store: 0 or 1
983 *---------------------------------------------------------------------------------------------------------------------------------------------------
986 irmp_store_bit (uint8_t value
)
988 if (irmp_bit
>= irmp_param
.address_offset
&& irmp_bit
< irmp_param
.address_end
)
990 if (irmp_param
.lsb_first
)
992 irmp_tmp_address
|= (((uint16_t) (value
)) << (irmp_bit
- irmp_param
.address_offset
)); // CV wants cast
996 irmp_tmp_address
<<= 1;
997 irmp_tmp_address
|= value
;
1000 else if (irmp_bit
>= irmp_param
.command_offset
&& irmp_bit
< irmp_param
.command_end
)
1002 if (irmp_param
.lsb_first
)
1004 irmp_tmp_command
|= (((uint16_t) (value
)) << (irmp_bit
- irmp_param
.command_offset
)); // CV wants cast
1008 irmp_tmp_command
<<= 1;
1009 irmp_tmp_command
|= value
;
1012 #if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1
1013 else if (irmp_param
.protocol
== IRMP_SAMSUNG_PROTOCOL
&& irmp_bit
>= SAMSUNG_ID_OFFSET
&& irmp_bit
< SAMSUNG_ID_OFFSET
+ SAMSUNG_ID_LEN
)
1015 irmp_tmp_id
|= (((uint16_t) (value
)) << (irmp_bit
- SAMSUNG_ID_OFFSET
)); // store with LSB first
1021 /*---------------------------------------------------------------------------------------------------------------------------------------------------
1023 * @details ISR routine, called 10000 times per second
1024 *---------------------------------------------------------------------------------------------------------------------------------------------------
1029 static uint8_t irmp_start_bit_detected
; // flag: start bit detected
1030 static uint8_t wait_for_space
; // flag: wait for data bit space
1031 static uint8_t wait_for_start_space
; // flag: wait for start bit space
1032 static uint8_t irmp_pulse_time
; // count bit time for pulse
1033 static uint8_t irmp_pause_time
; // count bit time for pause
1034 static uint16_t last_irmp_address
; // save last irmp address to recognize key repetition
1035 static uint16_t last_irmp_command
; // save last irmp command to recognize key repetition
1036 static uint16_t repetition_counter
; // SIRCS repeats frame 2-5 times with 45 ms pause
1037 #if IRMP_SUPPORT_DENON_PROTOCOL == 1
1038 static uint16_t last_irmp_denon_command
; // save last irmp command to recognize DENON frame repetition
1040 #if IRMP_SUPPORT_RC5_PROTOCOL == 1
1041 static uint8_t rc5_cmd_bit6
; // bit 6 of RC5 command is the inverted 2nd start bit
1043 #if IRMP_SUPPORT_RC5_PROTOCOL == 1 || IRMP_SUPPORT_RC6_PROTOCOL == 1
1044 static uint8_t rc5_last_pause
; // last pause value
1045 static uint8_t rc5_last_value
; // last bit value
1047 uint8_t irmp_input
; // input value
1049 irmp_input
= input(IRMP_PIN
);
1051 irmp_logIsr(irmp_input
); // log ir signal, if IRMP_LOGGING defined
1053 if (! irmp_ir_detected
) // ir code already detected?
1055 if (! irmp_start_bit_detected
) // start bit detected?
1057 if (!irmp_input
) // receiving burst?
1059 irmp_pulse_time
++; // increment counter
1063 if (irmp_pulse_time
) // it's dark....
1064 { // set flags for counting the time of darkness...
1065 irmp_start_bit_detected
= 1;
1066 wait_for_start_space
= 1;
1068 irmp_tmp_command
= 0;
1069 irmp_tmp_address
= 0;
1071 irmp_pause_time
= 1; // 1st pause: set to 1, not to 0!
1072 #if IRMP_SUPPORT_RC5_PROTOCOL == 1
1073 rc5_cmd_bit6
= 0; // fm 2010-03-07: bugfix: reset it after incomplete RC5 frame!
1078 repetition_counter
++;
1084 if (wait_for_start_space
) // we have received start bit...
1085 { // ...and are counting the time of darkness
1086 if (irmp_input
) // still dark?
1088 irmp_pause_time
++; // increment counter
1090 if (irmp_pause_time
> IRMP_TIMEOUT
) // timeout?
1092 DEBUG_PRINTF ("error 1: pause after start bit %d too long: %d\n", irmp_pulse_time
, irmp_pause_time
);
1093 irmp_start_bit_detected
= 0; // reset flags, let's wait for another start bit
1094 irmp_pulse_time
= 0;
1095 irmp_pause_time
= 0;
1099 { // receiving first data pulse!
1100 DEBUG_PRINTF ("start-bit: pulse = %d, pause = %d\n", irmp_pulse_time
, irmp_pause_time
);
1102 #if IRMP_SUPPORT_SIRCS_PROTOCOL == 1
1103 if (irmp_pulse_time
>= SIRCS_START_BIT_PULSE_LEN_MIN
&& irmp_pulse_time
<= SIRCS_START_BIT_PULSE_LEN_MAX
&&
1104 irmp_pause_time
>= SIRCS_START_BIT_PAUSE_LEN_MIN
&& irmp_pause_time
<= SIRCS_START_BIT_PAUSE_LEN_MAX
)
1106 DEBUG_PRINTF ("protocol = SIRCS, start bit timings: pulse: %2d - %2d, pause: %2d - %2d\n",
1107 SIRCS_START_BIT_PULSE_LEN_MIN
, SIRCS_START_BIT_PULSE_LEN_MAX
,
1108 SIRCS_START_BIT_PAUSE_LEN_MIN
, SIRCS_START_BIT_PAUSE_LEN_MAX
);
1109 memcpy_P (&irmp_param
, &sircs_param
, sizeof (IRMP_PARAMETER
));
1112 #endif // IRMP_SUPPORT_SIRCS_PROTOCOL == 1
1114 #if IRMP_SUPPORT_NEC_PROTOCOL == 1
1115 if (irmp_pulse_time
>= NEC_START_BIT_PULSE_LEN_MIN
&& irmp_pulse_time
<= NEC_START_BIT_PULSE_LEN_MAX
&&
1116 ((irmp_pause_time
>= NEC_START_BIT_PAUSE_LEN_MIN
&& irmp_pause_time
<= NEC_START_BIT_PAUSE_LEN_MAX
) ||
1117 (irmp_pause_time
>= NEC_REPEAT_START_BIT_PAUSE_LEN_MIN
&& irmp_pause_time
<= NEC_REPEAT_START_BIT_PAUSE_LEN_MAX
)))
1119 if (irmp_pause_time
<= NEC_REPEAT_START_BIT_PAUSE_LEN_MAX
)
1121 DEBUG_PRINTF ("protocol = NEC (repetition frame), start bit timings: pulse: %2d - %2d, pause: %2d - %2d\n",
1122 NEC_START_BIT_PULSE_LEN_MIN
, NEC_START_BIT_PULSE_LEN_MAX
,
1123 NEC_REPEAT_START_BIT_PAUSE_LEN_MIN
, NEC_REPEAT_START_BIT_PAUSE_LEN_MAX
);
1127 DEBUG_PRINTF ("protocol = NEC, start bit timings: pulse: %2d - %2d, pause: %2d - %2d\n",
1128 NEC_START_BIT_PULSE_LEN_MIN
, NEC_START_BIT_PULSE_LEN_MAX
,
1129 NEC_START_BIT_PAUSE_LEN_MIN
, NEC_START_BIT_PAUSE_LEN_MAX
);
1132 memcpy_P (&irmp_param
, &nec_param
, sizeof (IRMP_PARAMETER
));
1134 if (irmp_pause_time
<= NEC_REPEAT_START_BIT_PAUSE_LEN_MAX
)
1136 irmp_param
.address_offset
= 0;
1137 irmp_param
.address_end
= 0;
1138 irmp_param
.command_offset
= 0;
1139 irmp_param
.command_end
= 0;
1140 irmp_param
.complete_len
= 0;
1144 #endif // IRMP_SUPPORT_NEC_PROTOCOL == 1
1146 #if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1
1147 if (irmp_pulse_time
>= SAMSUNG_START_BIT_PULSE_LEN_MIN
&& irmp_pulse_time
<= SAMSUNG_START_BIT_PULSE_LEN_MAX
&&
1148 irmp_pause_time
>= SAMSUNG_START_BIT_PAUSE_LEN_MIN
&& irmp_pause_time
<= SAMSUNG_START_BIT_PAUSE_LEN_MAX
)
1150 DEBUG_PRINTF ("protocol = SAMSUNG, start bit timings: pulse: %2d - %2d, pause: %2d - %2d\n",
1151 SAMSUNG_START_BIT_PULSE_LEN_MIN
, SAMSUNG_START_BIT_PULSE_LEN_MAX
,
1152 SAMSUNG_START_BIT_PAUSE_LEN_MIN
, SAMSUNG_START_BIT_PAUSE_LEN_MAX
);
1153 memcpy_P (&irmp_param
, &samsung_param
, sizeof (IRMP_PARAMETER
));
1156 #endif // IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1
1158 #if IRMP_SUPPORT_MATSUSHITA_PROTOCOL == 1
1159 if (irmp_pulse_time
>= MATSUSHITA_START_BIT_PULSE_LEN_MIN
&& irmp_pulse_time
<= MATSUSHITA_START_BIT_PULSE_LEN_MAX
&&
1160 irmp_pause_time
>= MATSUSHITA_START_BIT_PAUSE_LEN_MIN
&& irmp_pause_time
<= MATSUSHITA_START_BIT_PAUSE_LEN_MAX
)
1161 { // it's MATSUSHITA
1162 DEBUG_PRINTF ("protocol = MATSUSHITA, start bit timings: pulse: %2d - %2d, pause: %2d - %2d\n",
1163 MATSUSHITA_START_BIT_PULSE_LEN_MIN
, MATSUSHITA_START_BIT_PULSE_LEN_MAX
,
1164 MATSUSHITA_START_BIT_PAUSE_LEN_MIN
, MATSUSHITA_START_BIT_PAUSE_LEN_MAX
);
1165 memcpy_P (&irmp_param
, &matsushita_param
, sizeof (IRMP_PARAMETER
));
1168 #endif // IRMP_SUPPORT_MATSUSHITA_PROTOCOL == 1
1170 #if IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1
1171 if (irmp_pulse_time
>= KASEIKYO_START_BIT_PULSE_LEN_MIN
&& irmp_pulse_time
<= KASEIKYO_START_BIT_PULSE_LEN_MAX
&&
1172 irmp_pause_time
>= KASEIKYO_START_BIT_PAUSE_LEN_MIN
&& irmp_pause_time
<= KASEIKYO_START_BIT_PAUSE_LEN_MAX
)
1174 DEBUG_PRINTF ("protocol = KASEIKYO, start bit timings: pulse: %2d - %2d, pause: %2d - %2d\n",
1175 KASEIKYO_START_BIT_PULSE_LEN_MIN
, KASEIKYO_START_BIT_PULSE_LEN_MAX
,
1176 KASEIKYO_START_BIT_PAUSE_LEN_MIN
, KASEIKYO_START_BIT_PAUSE_LEN_MAX
);
1177 memcpy_P (&irmp_param
, &kaseikyo_param
, sizeof (IRMP_PARAMETER
));
1180 #endif // IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1
1182 #if IRMP_SUPPORT_RECS80_PROTOCOL == 1
1183 if (irmp_pulse_time
>= RECS80_START_BIT_PULSE_LEN_MIN
&& irmp_pulse_time
<= RECS80_START_BIT_PULSE_LEN_MAX
&&
1184 irmp_pause_time
>= RECS80_START_BIT_PAUSE_LEN_MIN
&& irmp_pause_time
<= RECS80_START_BIT_PAUSE_LEN_MAX
)
1186 DEBUG_PRINTF ("protocol = RECS80, start bit timings: pulse: %2d - %2d, pause: %2d - %2d\n",
1187 RECS80_START_BIT_PULSE_LEN_MIN
, RECS80_START_BIT_PULSE_LEN_MAX
,
1188 RECS80_START_BIT_PAUSE_LEN_MIN
, RECS80_START_BIT_PAUSE_LEN_MAX
);
1189 memcpy_P (&irmp_param
, &recs80_param
, sizeof (IRMP_PARAMETER
));
1192 #endif // IRMP_SUPPORT_RECS80_PROTOCOL == 1
1194 #if IRMP_SUPPORT_RC5_PROTOCOL == 1
1195 if (((irmp_pulse_time
>= RC5_START_BIT_LEN_MIN
&& irmp_pulse_time
<= RC5_START_BIT_LEN_MAX
) ||
1196 (irmp_pulse_time
>= 2 * RC5_START_BIT_LEN_MIN
&& irmp_pulse_time
<= 2 * RC5_START_BIT_LEN_MAX
)) &&
1197 ((irmp_pause_time
>= RC5_START_BIT_LEN_MIN
&& irmp_pause_time
<= RC5_START_BIT_LEN_MAX
) ||
1198 (irmp_pause_time
>= 2 * RC5_START_BIT_LEN_MIN
&& irmp_pause_time
<= 2 * RC5_START_BIT_LEN_MAX
)))
1200 DEBUG_PRINTF ("protocol = RC5, start bit timings: pulse: %2d - %2d, pause: %2d - %2d\n",
1201 RC5_START_BIT_LEN_MIN
, RC5_START_BIT_LEN_MAX
,
1202 RC5_START_BIT_LEN_MIN
, RC5_START_BIT_LEN_MAX
);
1203 memcpy_P (&irmp_param
, &rc5_param
, sizeof (IRMP_PARAMETER
));
1204 rc5_last_pause
= irmp_pause_time
;
1206 if ((irmp_pulse_time
> RC5_START_BIT_LEN_MAX
&& irmp_pulse_time
<= 2 * RC5_START_BIT_LEN_MAX
) ||
1207 (irmp_pause_time
> RC5_START_BIT_LEN_MAX
&& irmp_pause_time
<= 2 * RC5_START_BIT_LEN_MAX
))
1210 rc5_cmd_bit6
= 1<<6;
1218 #endif // IRMP_SUPPORT_RC5_PROTOCOL == 1
1220 #if IRMP_SUPPORT_DENON_PROTOCOL == 1
1221 if ( (irmp_pulse_time
>= DENON_PULSE_LEN_MIN
&& irmp_pulse_time
<= DENON_PULSE_LEN_MAX
) &&
1222 ((irmp_pause_time
>= DENON_1_PAUSE_LEN_MIN
&& irmp_pause_time
<= DENON_1_PAUSE_LEN_MAX
) ||
1223 (irmp_pause_time
>= DENON_0_PAUSE_LEN_MIN
&& irmp_pause_time
<= DENON_0_PAUSE_LEN_MAX
)))
1225 DEBUG_PRINTF ("protocol = DENON, start bit timings: pulse: %2d - %2d, pause: %2d - %2d or %2d - %2d\n",
1226 DENON_PULSE_LEN_MIN
, DENON_PULSE_LEN_MAX
,
1227 DENON_1_PAUSE_LEN_MIN
, DENON_1_PAUSE_LEN_MAX
,
1228 DENON_0_PAUSE_LEN_MIN
, DENON_0_PAUSE_LEN_MAX
);
1229 memcpy_P (&irmp_param
, &denon_param
, sizeof (IRMP_PARAMETER
));
1232 #endif // IRMP_SUPPORT_DENON_PROTOCOL == 1
1234 #if IRMP_SUPPORT_RC6_PROTOCOL == 1
1235 if (irmp_pulse_time
>= RC6_START_BIT_PULSE_LEN_MIN
&& irmp_pulse_time
<= RC6_START_BIT_PULSE_LEN_MAX
&&
1236 irmp_pause_time
>= RC6_START_BIT_PAUSE_LEN_MIN
&& irmp_pause_time
<= RC6_START_BIT_PAUSE_LEN_MAX
)
1238 DEBUG_PRINTF ("protocol = RC6, start bit timings: pulse: %2d - %2d, pause: %2d - %2d\n",
1239 RC6_START_BIT_PULSE_LEN_MIN
, RC6_START_BIT_PULSE_LEN_MAX
,
1240 RC6_START_BIT_PAUSE_LEN_MIN
, RC6_START_BIT_PAUSE_LEN_MAX
);
1241 memcpy_P (&irmp_param
, &rc6_param
, sizeof (IRMP_PARAMETER
));
1246 #endif // IRMP_SUPPORT_RC6_PROTOCOL == 1
1248 #if IRMP_SUPPORT_RECS80EXT_PROTOCOL == 1
1249 if (irmp_pulse_time
>= RECS80EXT_START_BIT_PULSE_LEN_MIN
&& irmp_pulse_time
<= RECS80EXT_START_BIT_PULSE_LEN_MAX
&&
1250 irmp_pause_time
>= RECS80EXT_START_BIT_PAUSE_LEN_MIN
&& irmp_pause_time
<= RECS80EXT_START_BIT_PAUSE_LEN_MAX
)
1252 DEBUG_PRINTF ("protocol = RECS80EXT, start bit timings: pulse: %2d - %2d, pause: %2d - %2d\n",
1253 RECS80EXT_START_BIT_PULSE_LEN_MIN
, RECS80EXT_START_BIT_PULSE_LEN_MAX
,
1254 RECS80EXT_START_BIT_PAUSE_LEN_MIN
, RECS80EXT_START_BIT_PAUSE_LEN_MAX
);
1255 memcpy_P (&irmp_param
, &recs80ext_param
, sizeof (IRMP_PARAMETER
));
1258 #endif // IRMP_SUPPORT_RECS80EXT_PROTOCOL == 1
1260 #if IRMP_SUPPORT_NUBERT_PROTOCOL == 1
1261 if (irmp_pulse_time
>= NUBERT_START_BIT_PULSE_LEN_MIN
&& irmp_pulse_time
<= NUBERT_START_BIT_PULSE_LEN_MAX
&&
1262 irmp_pause_time
>= NUBERT_START_BIT_PAUSE_LEN_MIN
&& irmp_pause_time
<= NUBERT_START_BIT_PAUSE_LEN_MAX
)
1264 DEBUG_PRINTF ("protocol = NUBERT, start bit timings: pulse: %2d - %2d, pause: %2d - %2d\n",
1265 NUBERT_START_BIT_PULSE_LEN_MIN
, NUBERT_START_BIT_PULSE_LEN_MAX
,
1266 NUBERT_START_BIT_PAUSE_LEN_MIN
, NUBERT_START_BIT_PAUSE_LEN_MAX
);
1267 memcpy_P (&irmp_param
, &nubert_param
, sizeof (IRMP_PARAMETER
));
1270 #endif // IRMP_SUPPORT_NUBERT_PROTOCOL == 1
1273 DEBUG_PRINTF ("protocol = UNKNOWN\n");
1274 irmp_start_bit_detected
= 0; // wait for another start bit...
1277 if (irmp_start_bit_detected
)
1279 DEBUG_PRINTF ("pulse_1 = %2d - %2d\n", irmp_param
.pulse_1_len_min
, irmp_param
.pulse_1_len_max
);
1280 DEBUG_PRINTF ("pause_1 = %2d - %2d\n", irmp_param
.pause_1_len_min
, irmp_param
.pause_1_len_max
);
1281 if (irmp_param
.protocol
== IRMP_RC6_PROTOCOL
)
1283 DEBUG_PRINTF ("pulse_toggle = %2d - %2d\n", RC6_TOGGLE_BIT_LEN_MIN
, RC6_TOGGLE_BIT_LEN_MAX
);
1285 DEBUG_PRINTF ("pulse_0 = %2d - %2d\n", irmp_param
.pulse_0_len_min
, irmp_param
.pulse_0_len_max
);
1286 DEBUG_PRINTF ("pause_0 = %2d - %2d\n", irmp_param
.pause_0_len_min
, irmp_param
.pause_0_len_max
);
1287 DEBUG_PRINTF ("command_offset = %d\n", irmp_param
.command_offset
);
1288 DEBUG_PRINTF ("command_len = %d\n", irmp_param
.command_end
- irmp_param
.command_offset
);
1289 DEBUG_PRINTF ("complete_len = %d\n", irmp_param
.complete_len
);
1290 DEBUG_PRINTF ("stop_bit = %d\n", irmp_param
.stop_bit
);
1295 #if IRMP_SUPPORT_RC5_PROTOCOL == 1
1296 if (irmp_param
.protocol
== IRMP_RC5_PROTOCOL
)
1298 if (irmp_pause_time
> RC5_START_BIT_LEN_MAX
&& irmp_pause_time
<= 2 * RC5_START_BIT_LEN_MAX
)
1300 DEBUG_PRINTF ("[bit %2d: pulse = %2d, pause = %2d] ", irmp_bit
, irmp_pulse_time
, irmp_pause_time
);
1301 DEBUG_PUTCHAR ('1');
1302 DEBUG_PUTCHAR ('\n');
1305 else if (! rc5_last_value
)
1307 DEBUG_PRINTF ("[bit %2d: pulse = %2d, pause = %2d] ", irmp_bit
, irmp_pulse_time
, irmp_pause_time
);
1308 DEBUG_PUTCHAR ('0');
1309 DEBUG_PUTCHAR ('\n');
1314 #endif // IRMP_SUPPORT_RC5_PROTOCOL == 1
1316 #if IRMP_SUPPORT_DENON_PROTOCOL == 1
1317 if (irmp_param
.protocol
== IRMP_DENON_PROTOCOL
)
1319 DEBUG_PRINTF ("[bit %2d: pulse = %2d, pause = %2d] ", irmp_bit
, irmp_pulse_time
, irmp_pause_time
);
1321 if (irmp_pause_time
>= DENON_1_PAUSE_LEN_MIN
&& irmp_pause_time
<= DENON_1_PAUSE_LEN_MAX
)
1322 { // pause timings correct for "1"?
1323 DEBUG_PUTCHAR ('1'); // yes, store 1
1324 DEBUG_PUTCHAR ('\n');
1327 else // if (irmp_pause_time >= DENON_0_PAUSE_LEN_MIN && irmp_pause_time <= DENON_0_PAUSE_LEN_MAX)
1328 { // pause timings correct for "0"?
1329 DEBUG_PUTCHAR ('0'); // yes, store 0
1330 DEBUG_PUTCHAR ('\n');
1334 #endif // IRMP_SUPPORT_DENON_PROTOCOL == 1
1336 irmp_pulse_time
= 1; // set counter to 1, not 0
1337 irmp_pause_time
= 0;
1338 wait_for_start_space
= 0;
1341 else if (wait_for_space
) // the data section....
1342 { // counting the time of darkness....
1343 uint8_t got_light
= FALSE
;
1345 if (irmp_input
) // still dark?
1347 if (irmp_bit
== irmp_param
.complete_len
&& irmp_param
.stop_bit
== 1)
1349 if (irmp_pulse_time
>= irmp_param
.pulse_0_len_min
&& irmp_pulse_time
<= irmp_param
.pulse_0_len_max
)
1352 if (irmp_param
.protocol
!= IRMP_RC5_PROTOCOL
)
1354 DEBUG_PRINTF ("stop bit detected\n");
1357 irmp_param
.stop_bit
= 0;
1361 DEBUG_PRINTF ("stop bit timing wrong\n");
1363 irmp_start_bit_detected
= 0; // wait for another start bit...
1364 irmp_pulse_time
= 0;
1365 irmp_pause_time
= 0;
1370 irmp_pause_time
++; // increment counter
1372 #if IRMP_SUPPORT_SIRCS_PROTOCOL == 1
1373 if (irmp_param
.protocol
== IRMP_SIRCS_PROTOCOL
&& // Sony has a variable number of bits:
1374 irmp_pause_time
> SIRCS_PAUSE_LEN_MAX
&& // minimum is 12
1375 irmp_bit
>= 12 - 1) // pause too long?
1376 { // yes, break and close this frame
1377 irmp_param
.complete_len
= irmp_bit
+ 1; // set new complete length
1378 got_light
= TRUE
; // this is a lie, but helps (generates stop bit)
1379 irmp_param
.command_end
= irmp_param
.command_offset
+ irmp_bit
+ 1; // correct command length
1380 irmp_pause_time
= SIRCS_PAUSE_LEN_MAX
- 1; // correct pause length
1384 #if IRMP_SUPPORT_RC5_PROTOCOL == 1
1385 if (irmp_param
.protocol
== IRMP_RC5_PROTOCOL
&&
1386 irmp_pause_time
> 2 * RC5_BIT_LEN_MAX
&& irmp_bit
>= RC5_COMPLETE_DATA_LEN
- 2 && !irmp_param
.stop_bit
)
1387 { // special rc5 decoder
1388 got_light
= TRUE
; // this is a lie, but generates a stop bit ;-)
1389 irmp_param
.stop_bit
= TRUE
; // set flag
1393 #if IRMP_SUPPORT_RC6_PROTOCOL == 1
1394 if (irmp_param
.protocol
== IRMP_RC6_PROTOCOL
&&
1395 irmp_pause_time
> 2 * RC6_BIT_LEN_MAX
&& irmp_bit
>= irmp_param
.complete_len
- 2 && !irmp_param
.stop_bit
)
1396 { // special rc6 decoder
1397 got_light
= TRUE
; // this is a lie, but generates a stop bit ;-)
1398 irmp_param
.stop_bit
= TRUE
; // set flag
1402 if (irmp_pause_time
> IRMP_TIMEOUT
) // timeout?
1404 if (irmp_bit
== irmp_param
.complete_len
- 1 && irmp_param
.stop_bit
== 0)
1410 DEBUG_PRINTF ("error 2: pause %d after data bit %d too long\n", irmp_pause_time
, irmp_bit
);
1412 irmp_start_bit_detected
= 0; // wait for another start bit...
1413 irmp_pulse_time
= 0;
1414 irmp_pause_time
= 0;
1426 DEBUG_PRINTF ("[bit %2d: pulse = %2d, pause = %2d] ", irmp_bit
, irmp_pulse_time
, irmp_pause_time
);
1428 #if IRMP_SUPPORT_RC5_PROTOCOL == 1
1429 if (irmp_param
.protocol
== IRMP_RC5_PROTOCOL
) // special rc5 decoder
1431 if (irmp_pulse_time
> RC5_BIT_LEN_MAX
&& irmp_pulse_time
<= 2 * RC5_BIT_LEN_MAX
)
1433 DEBUG_PUTCHAR ('1');
1435 DEBUG_PUTCHAR ('0');
1436 DEBUG_PUTCHAR ('\n');
1441 else // if (irmp_pulse_time >= RC5_BIT_LEN_MIN && irmp_pulse_time <= RC5_BIT_LEN_MAX)
1445 if (rc5_last_pause
> RC5_BIT_LEN_MAX
&& rc5_last_pause
<= 2 * RC5_BIT_LEN_MAX
)
1447 rc5_value
= rc5_last_value
? 0 : 1;
1448 rc5_last_value
= rc5_value
;
1452 rc5_value
= rc5_last_value
;
1455 DEBUG_PUTCHAR (rc5_value
+ '0');
1456 DEBUG_PUTCHAR ('\n');
1457 irmp_store_bit (rc5_value
);
1460 rc5_last_pause
= irmp_pause_time
;
1466 #if IRMP_SUPPORT_RC6_PROTOCOL == 1
1467 if (irmp_param
.protocol
== IRMP_RC6_PROTOCOL
) // special rc6 decoder
1470 { // handle toggle bit, which is 2 times longer than other bits
1474 if (irmp_pulse_time
> RC6_TOGGLE_BIT_LEN_MAX
&& irmp_pause_time
> RC6_TOGGLE_BIT_LEN_MAX
)
1476 DEBUG_PUTCHAR ('1');
1480 DEBUG_PUTCHAR ('0');
1483 DEBUG_PUTCHAR ('\n');
1487 if (irmp_pulse_time
> RC6_BIT_LEN_MAX
&& irmp_pulse_time
<= 2 * RC6_BIT_LEN_MAX
)
1489 DEBUG_PUTCHAR ('0');
1491 DEBUG_PUTCHAR ('1');
1492 DEBUG_PUTCHAR ('\n');
1496 else // if (irmp_pulse_time >= RC6_BIT_LEN_MIN && irmp_pulse_time <= RC6_BIT_LEN_MAX)
1500 if (rc5_last_pause
> RC6_BIT_LEN_MAX
&& rc5_last_pause
<= 2 * RC6_BIT_LEN_MAX
)
1502 rc5_value
= rc5_last_value
? 0 : 1;
1503 rc5_last_value
= rc5_value
;
1507 rc5_value
= rc5_last_value
;
1510 if (irmp_bit
== 1 && rc5_value
== 0)
1512 irmp_param
.complete_len
= RC6_COMPLETE_DATA_LEN_LONG
;
1515 DEBUG_PUTCHAR (rc5_value
+ '0');
1516 DEBUG_PUTCHAR ('\n');
1517 irmp_store_bit (rc5_value
);
1520 rc5_last_pause
= irmp_pause_time
;
1529 #if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1
1530 if (irmp_param
.protocol
== IRMP_SAMSUNG_PROTOCOL
&& irmp_bit
== 16) // Samsung: 16th bit
1532 if (irmp_pulse_time
>= SAMSUNG_PULSE_LEN_MIN
&& irmp_pulse_time
<= SAMSUNG_PULSE_LEN_MAX
&&
1533 irmp_pause_time
>= SAMSUNG_START_BIT_PAUSE_LEN_MIN
&& irmp_pause_time
<= SAMSUNG_START_BIT_PAUSE_LEN_MAX
)
1535 DEBUG_PRINTF ("SYNC\n");
1540 else if (irmp_pulse_time
>= SAMSUNG_PULSE_LEN_MIN
&& irmp_pulse_time
<= SAMSUNG_PULSE_LEN_MAX
)
1542 if (irmp_pause_time
>= SAMSUNG_1_PAUSE_LEN_MIN
&& irmp_pause_time
<= SAMSUNG_1_PAUSE_LEN_MAX
)
1544 DEBUG_PUTCHAR ('1');
1545 DEBUG_PUTCHAR ('\n');
1551 DEBUG_PUTCHAR ('0');
1552 DEBUG_PUTCHAR ('\n');
1557 DEBUG_PRINTF ("Switching to SAMSUNG32 protocol\n");
1559 irmp_param
.protocol
= IRMP_SAMSUNG32_PROTOCOL
;
1560 irmp_param
.command_offset
= SAMSUNG32_COMMAND_OFFSET
;
1561 irmp_param
.command_end
= SAMSUNG32_COMMAND_OFFSET
+ SAMSUNG32_COMMAND_LEN
;
1562 irmp_param
.complete_len
= SAMSUNG32_COMPLETE_DATA_LEN
;
1565 { // timing incorrect!
1566 DEBUG_PRINTF ("error 3: timing not correct: data bit %d, pulse: %d, pause: %d\n", irmp_bit
, irmp_pulse_time
, irmp_pause_time
);
1567 irmp_start_bit_detected
= 0; // reset flags and wait for next start bit
1568 irmp_pause_time
= 0;
1571 irmp_pulse_time
= 1; // set counter to 1, not 0
1574 #endif // IRMP_SUPPORT_SAMSUNG_PROTOCOL
1576 if (irmp_pulse_time
>= irmp_param
.pulse_1_len_min
&& irmp_pulse_time
<= irmp_param
.pulse_1_len_max
&&
1577 irmp_pause_time
>= irmp_param
.pause_1_len_min
&& irmp_pause_time
<= irmp_param
.pause_1_len_max
)
1578 { // pulse & pause timings correct for "1"?
1579 DEBUG_PUTCHAR ('1');
1580 DEBUG_PUTCHAR ('\n');
1584 else if (irmp_pulse_time
>= irmp_param
.pulse_0_len_min
&& irmp_pulse_time
<= irmp_param
.pulse_0_len_max
&&
1585 irmp_pause_time
>= irmp_param
.pause_0_len_min
&& irmp_pause_time
<= irmp_param
.pause_0_len_max
)
1586 { // pulse & pause timings correct for "0"?
1587 DEBUG_PUTCHAR ('0');
1588 DEBUG_PUTCHAR ('\n');
1593 { // timing incorrect!
1594 DEBUG_PRINTF ("error 3: timing not correct: data bit %d, pulse: %d, pause: %d\n", irmp_bit
, irmp_pulse_time
, irmp_pause_time
);
1595 irmp_start_bit_detected
= 0; // reset flags and wait for next start bit
1596 irmp_pause_time
= 0;
1599 irmp_pulse_time
= 1; // set counter to 1, not 0
1603 { // counting the pulse length ...
1604 if (!irmp_input
) // still light?
1606 irmp_pulse_time
++; // increment counter
1610 wait_for_space
= 1; // let's count the time (see above)
1611 irmp_pause_time
= 1; // set pause counter to 1, not 0
1615 if (irmp_bit
== irmp_param
.complete_len
&& irmp_param
.stop_bit
== 0) // enough bits received?
1617 // if SIRCS/SAMSUNG32 protocol and the code will be repeated within 50 ms, we will ignore it.
1618 if ((irmp_param
.protocol
== IRMP_SIRCS_PROTOCOL
||
1619 irmp_param
.protocol
== IRMP_SAMSUNG32_PROTOCOL
||
1620 irmp_param
.protocol
== IRMP_NUBERT_PROTOCOL
) &&
1621 last_irmp_command
== irmp_tmp_command
&& repetition_counter
< AUTO_REPETITION_LEN
)
1623 DEBUG_PRINTF ("code skipped, recognized SIRCS, SAMSUNG32 or NUBERT repetition, counter = %d, auto repetition len = %d\n",
1624 repetition_counter
, AUTO_REPETITION_LEN
);
1625 repetition_counter
= 0;
1629 DEBUG_PRINTF ("code detected, length = %d\n", irmp_bit
);
1630 irmp_ir_detected
= TRUE
;
1632 #if IRMP_SUPPORT_DENON_PROTOCOL == 1
1633 if (irmp_param
.protocol
== IRMP_DENON_PROTOCOL
)
1634 { // check for repetition frame
1635 if ((~irmp_tmp_command
& 0x3FF) == last_irmp_denon_command
) // command bits must be inverted
1637 irmp_tmp_command
= last_irmp_denon_command
; // use command received before!
1639 irmp_protocol
= irmp_param
.protocol
; // store protocol
1640 irmp_address
= irmp_tmp_address
; // store address
1641 irmp_command
= irmp_tmp_command
; // store command
1645 DEBUG_PRINTF ("waiting for inverted command repetition\n");
1646 irmp_ir_detected
= FALSE
;
1647 last_irmp_denon_command
= irmp_tmp_command
;
1651 #endif // IRMP_SUPPORT_DENON_PROTOCOL
1653 #if IRMP_SUPPORT_NEC_PROTOCOL == 1
1654 if (irmp_param
.protocol
== IRMP_NEC_PROTOCOL
&& irmp_bit
== 0) // repetition frame
1656 irmp_protocol
= irmp_param
.protocol
;
1657 irmp_address
= last_irmp_address
; // address is last address
1658 irmp_command
= last_irmp_command
; // command is last command
1659 irmp_flags
|= IRMP_FLAG_REPETITION
;
1662 #endif // IRMP_SUPPORT_NEC_PROTOCOL
1664 irmp_protocol
= irmp_param
.protocol
;
1665 irmp_address
= irmp_tmp_address
; // store address
1666 #if IRMP_SUPPORT_NEC_PROTOCOL == 1
1667 last_irmp_address
= irmp_tmp_address
; // store as last address, too
1670 #if IRMP_SUPPORT_RC5_PROTOCOL == 1
1671 irmp_tmp_command
|= rc5_cmd_bit6
; // store bit 6
1673 irmp_command
= irmp_tmp_command
; // store command
1675 #if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1
1676 irmp_id
= irmp_tmp_id
;
1681 if (irmp_ir_detected
)
1683 if (last_irmp_command
== irmp_command
&&
1684 last_irmp_address
== irmp_address
&&
1685 repetition_counter
< IRMP_REPETITION_TIME
)
1687 irmp_flags
|= IRMP_FLAG_REPETITION
;
1690 last_irmp_address
= irmp_tmp_address
; // store as last address, too
1691 last_irmp_command
= irmp_tmp_command
; // store as last command, too
1693 repetition_counter
= 0;
1696 irmp_start_bit_detected
= 0; // and wait for next start bit
1697 irmp_tmp_command
= 0;
1698 irmp_pulse_time
= 0;
1699 irmp_pause_time
= 0;
1707 // main function - for unix/linux + windows only!
1709 // Compile it under linux with:
1710 // cc irmp.c -o irmp
1712 // usage: ./irmp [-v|-s|-a] < file
1715 main (int argc
, char ** argv
)
1718 int verbose
= FALSE
;
1719 int analyze
= FALSE
;
1725 int min_pulse_long
= 100000;
1726 int max_pulse_long
= 0;
1727 int sum_pulses_long
= 0;
1728 int n_pulses_long
= 0;
1730 int min_pulse_short
= 100000;
1731 int max_pulse_short
= 0;
1732 int sum_pulses_short
= 0;
1733 int n_pulses_short
= 0;
1735 int min_pause_long
= 100000;
1736 int max_pause_long
= 0;
1737 int sum_pauses_long
= 0;
1738 int n_pauses_long
= 0;
1740 int min_pause_short
= 100000;
1741 int max_pause_short
= 0;
1742 int sum_pauses_short
= 0;
1743 int n_pauses_short
= 0;
1745 int min_start_pulse
= 100000;
1746 int max_start_pulse
= 0;
1747 int sum_start_pulses
= 0;
1748 int n_start_pulses
= 0;
1750 int min_start_pause
= 100000;
1751 int max_start_pause
= 0;
1752 int sum_start_pauses
= 0;
1753 int n_start_pauses
= 0;
1755 int first_pulse
= TRUE
;
1756 int first_pause
= TRUE
;
1758 IRMP_DATA irmp_data
;
1762 if (! strcmp (argv
[1], "-v"))
1766 else if (! strcmp (argv
[1], "-a"))
1771 else if (! strcmp (argv
[1], "-s"))
1779 while ((ch
= getchar ()) != EOF
)
1781 if (ch
== '_' || ch
== '0')
1785 if (verbose
&& pause
> 0)
1787 printf ("pause: %d\n", pause
);
1791 if (min_start_pause
> pause
)
1793 min_start_pause
= pause
;
1795 if (max_start_pause
< pause
)
1797 max_start_pause
= pause
;
1800 sum_start_pauses
+= pause
;
1801 first_pause
= FALSE
;
1807 if (pause
> 100) // perhaps repetition frame follows
1814 if (min_pause_long
> pause
)
1816 min_pause_long
= pause
;
1818 if (max_pause_long
< pause
)
1820 max_pause_long
= pause
;
1823 sum_pauses_long
+= pause
;
1828 if (min_pause_short
> pause
)
1830 min_pause_short
= pause
;
1832 if (max_pause_short
< pause
)
1834 max_pause_short
= pause
;
1837 sum_pauses_short
+= pause
;
1846 else if (ch
== 0xaf || ch
== '-' || ch
== '1')
1852 printf ("pulse: %d ", pulse
);
1856 if (min_start_pulse
> pulse
)
1858 min_start_pulse
= pulse
;
1860 if (max_start_pulse
< pulse
)
1862 max_start_pulse
= pulse
;
1865 sum_start_pulses
+= pulse
;
1866 first_pulse
= FALSE
;
1872 if (min_pulse_long
> pulse
)
1874 min_pulse_long
= pulse
;
1876 if (max_pulse_long
< pulse
)
1878 max_pulse_long
= pulse
;
1881 sum_pulses_long
+= pulse
;
1885 if (min_pulse_short
> pulse
)
1887 min_pulse_short
= pulse
;
1889 if (max_pulse_short
< pulse
)
1891 max_pulse_short
= pulse
;
1894 sum_pulses_short
+= pulse
;
1903 else if (ch
== '\n')
1907 if (verbose
&& pause
> 0)
1909 printf ("pause: %d\n", pause
);
1915 for (i
= 0; i
< 8000; i
++) // newline: long pause of 800 msec
1925 puts ("-------------------------------------------------------------------");
1928 while ((ch
= getchar()) != '\n' && ch
!= EOF
)
1930 if (ch
!= '\r') // ignore CR in DOS/Windows files
1945 if (irmp_get_data (&irmp_data
))
1947 printf ("protcol = %d, address = 0x%04x, code = 0x%04x, flags = 0x%02x\n",
1948 irmp_data
.protocol
, irmp_data
.address
, irmp_data
.command
, irmp_data
.flags
);
1954 printf ("\nSTATITSTICS:\n");
1955 printf ("---------------------------------\n");
1956 printf ("number of start pulses: %d\n", n_start_pulses
);
1957 printf ("minimum start pulse length: %d usec\n", (F_INTERRUPTS
* min_start_pulse
) / 100);
1958 printf ("maximum start pulse length: %d usec\n", (F_INTERRUPTS
* max_start_pulse
) / 100);
1959 if (n_start_pulses
> 0)
1961 printf ("average start pulse length: %d usec\n", ((F_INTERRUPTS
* sum_start_pulses
) / n_start_pulses
) / 100);
1964 printf ("number of start pauses: %d\n", n_start_pauses
);
1965 if (n_start_pauses
> 0)
1967 printf ("minimum start pause length: %d usec\n", (F_INTERRUPTS
* min_start_pause
) / 100);
1968 printf ("maximum start pause length: %d usec\n", (F_INTERRUPTS
* max_start_pause
) / 100);
1969 printf ("average start pause length: %d usec\n", ((F_INTERRUPTS
* sum_start_pauses
) / n_start_pauses
) / 100);
1972 printf ("number of long pulses: %d\n", n_pulses_long
);
1973 if (n_pulses_long
> 0)
1975 printf ("minimum long pulse length: %d usec\n", (F_INTERRUPTS
* min_pulse_long
) / 100);
1976 printf ("maximum long pulse length: %d usec\n", (F_INTERRUPTS
* max_pulse_long
) / 100);
1977 printf ("average long pulse length: %d usec\n", ((F_INTERRUPTS
* sum_pulses_long
) / n_pulses_long
) / 100);
1980 printf ("number of short pulses: %d\n", n_pulses_short
);
1981 if (n_pulses_short
> 0)
1983 printf ("minimum short pulse length: %d usec\n", (F_INTERRUPTS
* min_pulse_short
) / 100);
1984 printf ("maximum short pulse length: %d usec\n", (F_INTERRUPTS
* max_pulse_short
) / 100);
1985 printf ("average short pulse length: %d usec\n", ((F_INTERRUPTS
* sum_pulses_short
) / n_pulses_short
) / 100);
1989 printf ("number of long pauses: %d\n", n_pauses_long
);
1990 if (n_pauses_long
> 0)
1992 printf ("minimum long pause length: %d usec\n", (F_INTERRUPTS
* min_pause_long
) / 100);
1993 printf ("maximum long pause length: %d usec\n", (F_INTERRUPTS
* max_pause_long
) / 100);
1994 printf ("average long pause length: %d usec\n", ((F_INTERRUPTS
* sum_pauses_long
) / n_pauses_long
) / 100);
1997 printf ("number of short pauses: %d\n", n_pauses_short
);
1998 if (n_pauses_short
> 0)
2000 printf ("minimum short pause length: %d usec\n", (F_INTERRUPTS
* min_pause_short
) / 100);
2001 printf ("maximum short pause length: %d usec\n", (F_INTERRUPTS
* max_pause_short
) / 100);
2002 printf ("average short pause length: %d usec\n", ((F_INTERRUPTS
* sum_pauses_short
) / n_pauses_short
) / 100);