]> cloudbase.mooo.com Git - irmp.git/blob - irmp.c
1st checkin, version 1.0
[irmp.git] / irmp.c
1 /*---------------------------------------------------------------------------------------------------------------------------------------------------
2 * irmp.c - infrared multi-protocol decoder, supports several remote control protocols
3 *
4 * Copyright (c) 2009-2010 Frank Meyer - frank(at)fli4l.de
5 *
6 * ATMEGA88 @ 8 MHz
7 *
8 * Typical manufacturers:
9 *
10 * SIRCS - Sony
11 * NEC - NEC, Yamaha, Canon, Tevion, Harman/Kardon, Hitachi, JVC, Pioneer, Toshiba, Xoro, Orion, and many other Japanese manufacturers
12 * SAMSUNG - Samsung
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
17 * DENON - Denon
18 * RC6 - Philips and other European manufacturers
19 * APPLE - Apple
20 * NUBERT - Nubert Subwoofer System
21 * PANASONIC - Panasonic (older, yet not implemented)
22 *
23 *---------------------------------------------------------------------------------------------------------------------------------------------------
24 *
25 * SIRCS
26 * -----
27 *
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
30 *
31 * start bit: data "0": data "1": stop bit:
32 * -----------------_________ ------_____ ------------______
33 * 2400us 600us 600us 600us 1200us 600 us no stop bit
34 *
35 *---------------------------------------------------------------------------------------------------------------------------------------------------
36 *
37 * NEC + extended NEC
38 * -------------------------
39 *
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
43 *
44 * start bit: data "0": data "1": stop bit:
45 * -----------------_________ ------______ ------________________ ------______....
46 * 9000us 4500us 560us 560us 560us 1690 us 560us
47 *
48 *
49 * Repetition frame:
50 *
51 * -----------------_________------______ .... ~100ms Pause, then repeat
52 * 9000us 2250us 560us
53 *
54 *---------------------------------------------------------------------------------------------------------------------------------------------------
55 *
56 * SAMSUNG
57 * -------
58 *
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
62 *
63 * start bit: data "0": data "1": sync bit: stop bit:
64 * ----------______________ ------______ ------________________ ------______________ ------______....
65 * 4500us 4500us 550us 450us 550us 1450us 550us 4500us 550us
66 *
67 *---------------------------------------------------------------------------------------------------------------------------------------------------
68 *
69 * SAMSUNG32
70 * ----------
71 *
72 * frame: 1 start bit + 32 data bits + 1 stop bit
73 * data: 16 address bits + 16 command bits
74 *
75 * start bit: data "0": data "1": stop bit:
76 * ----------______________ ------______ ------________________ ------______....
77 * 4500us 4500us 550us 450us 550us 1450us 550us
78 *
79 *---------------------------------------------------------------------------------------------------------------------------------------------------
80 *
81 * MATSUSHITA
82 * ----------
83 *
84 * frame: 1 start bit + 24 data bits + 1 stop bit
85 * data: 6 custom bits + 6 command bits + 12 address bits
86 *
87 * start bit: data "0": data "1": stop bit:
88 * ----------_________ ------______ ------________________ ------______....
89 * 3488us 3488us 872us 872us 872us 2616us 872us
90 *
91 *---------------------------------------------------------------------------------------------------------------------------------------------------
92 *
93 * KASEIKYO
94 * --------
95 *
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
98 *
99 * start bit: data "0": data "1": stop bit:
100 * ----------______ ------______ ------________________ ------______....
101 * 3380us 1690us 423us 423us 423us 1269us 423us
102 *
103 *---------------------------------------------------------------------------------------------------------------------------------------------------
104 *
105 * RECS80
106 * ------
107 *
108 * frame: 2 start bits + 10 data bits + 1 stop bit
109 * data: 1 toggle bit + 3 address bits + 6 command bits
110 *
111 * start bit: data "0": data "1": stop bit:
112 * -----_____________________ -----____________ -----______________ ------_______....
113 * 158us 7432us 158us 4902us 158us 7432us 158us
114 *
115 *---------------------------------------------------------------------------------------------------------------------------------------------------
116 *
117 * RECS80EXT
118 * ---------
119 *
120 * frame: 2 start bits + 11 data bits + 1 stop bit
121 * data: 1 toggle bit + 4 address bits + 6 command bits
122 *
123 * start bit: data "0": data "1": stop bit:
124 * -----_____________________ -----____________ -----______________ ------_______....
125 * 158us 3637us 158us 4902us 158us 7432us 158us
126 *
127 *---------------------------------------------------------------------------------------------------------------------------------------------------
128 *
129 * RC5 + RC5X
130 * ----------
131 *
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
136 *
137 * start bit: data "0": data "1":
138 * ______----- ------______ ______------
139 * 889us 889us 889us 889us 889us 889us
140 *
141 *---------------------------------------------------------------------------------------------------------------------------------------------------
142 *
143 * DENON
144 * -----
145 *
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
148 *
149 * data "0": data "1":
150 * ------________________ ------______________
151 * 275us 1050us 275us 1900us
152 *
153 *---------------------------------------------------------------------------------------------------------------------------------------------------
154 *
155 * RC6
156 * ---
157 *
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
160 *
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
164 *
165 *---------------------------------------------------------------------------------------------------------------------------------------------------
166 *
167 * APPLE
168 * -----
169 *
170 * frame: 1 start bit + 32 data bits + 1 stop bit
171 * data: 16 address bits + 11100000 + 8 command bits
172 *
173 * start bit: data "0": data "1": stop bit:
174 * -----------------_________ ------______ ------________________ ------______....
175 * 9000us 4500us 560us 560us 560us 1690 us 560us
176 *
177 *---------------------------------------------------------------------------------------------------------------------------------------------------
178 *
179 * NUBERT (subwoofer system)
180 * -------------------------
181 *
182 * frame: 1 start bit + 10 data bits + 1 stop bit
183 * data: 0 address bits + 10 command bits ?
184 *
185 * start bit: data "0": data "1": stop bit:
186 * ----------_____ ------______ ------________________ ------______....
187 * 1340us 340us 500us 1300us 1340us 340us 500us
188 *
189 *---------------------------------------------------------------------------------------------------------------------------------------------------
190 *
191 * PANASONIC (older protocol, yet not implemented, see also MATSUSHITA, timing very similar)
192 * -----------------------------------------------------------------------------------------
193 *
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
196 *
197 * European version: T = 456us
198 * USA & Canada version: T = 422us
199 *
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)
205 *
206 *---------------------------------------------------------------------------------------------------------------------------------------------------
207 *
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 *---------------------------------------------------------------------------------------------------------------------------------------------------
213 */
214
215 #if defined(__PCM__) || defined(__PCB__) || defined(__PCH__) // CCS PIC Compiler instead of AVR
216 #define PIC_CCS_COMPILER
217 #endif
218
219 #ifdef unix // test on linux/unix
220 #include <stdio.h>
221 #include <unistd.h>
222 #include <stdlib.h>
223 #include <string.h>
224 #include <inttypes.h>
225
226 #define DEBUG
227 #define PROGMEM
228 #define memcpy_P memcpy
229
230 #else // not unix:
231
232 #ifdef WIN32
233 #include <stdio.h>
234 #include <string.h>
235 typedef unsigned char uint8_t;
236 typedef unsigned short uint16_t;
237 #define DEBUG
238 #define PROGMEM
239 #define memcpy_P memcpy
240
241 #else
242
243 #ifndef CODEVISION
244
245 #ifdef PIC_CCS_COMPILER
246
247 #include <string.h>
248 typedef unsigned int8 uint8_t;
249 typedef unsigned int16 uint16_t;
250 #define PROGMEM
251 #define memcpy_P memcpy
252
253 #else // AVR:
254
255 #include <inttypes.h>
256 #include <stdio.h>
257 #include <string.h>
258 #include <avr/io.h>
259 #include <util/delay.h>
260 #include <avr/pgmspace.h>
261
262 #endif // PIC_CCS_COMPILER
263 #endif // CODEVISION
264
265 #endif // windows
266 #endif // unix
267
268 #include "irmp.h"
269
270 /*---------------------------------------------------------------------------------------------------------------------------------------------------
271 * Change settings from 1 to 0 if you want to disable one or more decoders.
272 * This saves program space.
273 * 1 enable decoder
274 * 0 disable decoder
275 *---------------------------------------------------------------------------------------------------------------------------------------------------
276 */
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
288
289 /*---------------------------------------------------------------------------------------------------------------------------------------------------
290 * Change hardware pin here:
291 *---------------------------------------------------------------------------------------------------------------------------------------------------
292 */
293 #ifdef PIC_CCS_COMPILER // PIC CCS Compiler:
294
295 #define IRMP_PIN PIN_B4 // use PB4 as IR input on PIC
296
297 #else // AVR:
298
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
303
304 #define input(x) ((x) & (1 << IRMP_BIT))
305 #endif
306
307 /*---------------------------------------------------------------------------------------------------------------------------------------------------
308 * Set IRMP_LOGGING to 1 if want to log data to UART with 9600Bd
309 *---------------------------------------------------------------------------------------------------------------------------------------------------
310 */
311 #define IRMP_LOGGING 0 // 1: log IR signal (scan), 0: do not (default)
312
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
315
316 #define MIN_TOLERANCE_10 0.9 // -10%
317 #define MAX_TOLERANCE_10 1.1 // +10%
318
319 #define MIN_TOLERANCE_20 0.8 // -20%
320 #define MAX_TOLERANCE_20 1.2 // +20%
321
322 #define MIN_TOLERANCE_30 0.7 // -30%
323 #define MAX_TOLERANCE_30 1.3 // +30%
324
325 #define MIN_TOLERANCE_40 0.6 // -40%
326 #define MAX_TOLERANCE_40 1.4 // +40%
327
328 #define MIN_TOLERANCE_50 0.5 // -50%
329 #define MAX_TOLERANCE_50 1.5 // +50%
330
331 #define MIN_TOLERANCE_60 0.4 // -60%
332 #define MAX_TOLERANCE_60 1.6 // +60%
333
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)
344
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)
357
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)
368
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)
379
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)
390
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)
401
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)
406
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)
413
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)
422
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)
433
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)
446
447 #define AUTO_REPETITION_LEN (uint16_t)(F_INTERRUPTS * AUTO_REPETITION_TIME + 0.5) // use uint16_t!
448
449 #ifdef DEBUG
450 #define DEBUG_PUTCHAR(a) { if (! silent) { putchar (a); } }
451 #define DEBUG_PRINTF(...) { if (! silent) { printf (__VA_ARGS__); } }
452 static int silent;
453 #else
454 #define DEBUG_PUTCHAR(a)
455 #define DEBUG_PRINTF(...)
456 #endif
457
458 #if IRMP_LOGGING == 1
459 #define irmp_logIsr(x) irmp_logIr((x) ? 1:0)
460 #define UART_BAUD 9600L
461
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
465
466 #ifdef CODEVISION
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!
469 #endif
470
471 #else // not CODEVISION
472
473 #define BAUD_ERROR ((BAUD_REAL*1000)/UART_BAUD-1000) // error in promille
474
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!
477 #endif
478
479 #endif // CODEVISION
480
481 /*---------------------------------------------------------------------------------------------------------------------------------------------------
482 * Initialize UART
483 * @details Initializes UART
484 *---------------------------------------------------------------------------------------------------------------------------------------------------
485 */
486 void
487 irmp_uart_init (void)
488 {
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)
492 }
493
494 /*---------------------------------------------------------------------------------------------------------------------------------------------------
495 * Send character
496 * @details Sends character
497 * @param ch character to be transmitted
498 *---------------------------------------------------------------------------------------------------------------------------------------------------
499 */
500 void
501 irmp_uart_putc (unsigned char ch)
502 {
503 while (!(UCSR0A & (1<<UDRE0)))
504 {
505 ;
506 }
507
508 UDR0 = ch;
509 }
510
511 /*---------------------------------------------------------------------------------------------------------------------------------------------------
512 * Log IR signal
513 *---------------------------------------------------------------------------------------------------------------------------------------------------
514 */
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
518
519 static void
520 irmp_logIr (uint8_t val)
521 {
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
526
527 if ((val == 0) && (s_startcycles < c_startcycles) && !s_dataIdx) // prevent that single random zeros init logging
528 {
529 ++s_startcycles;
530 }
531 else
532 {
533 s_startcycles = 0;
534
535 if ( (val == 0) // start or continue logging on "0"
536 || ((val == 1) && (s_dataIdx != 0))) // "1" cannot init logging
537 {
538 if (val)
539 { // set or clear bit in bitarray
540 s_data[(s_dataIdx / 8)] |= (1<<(s_dataIdx % 8));
541 }
542 else
543 {
544 s_data[(s_dataIdx / 8)] &= ~(1<<(s_dataIdx % 8));
545 }
546
547 ++s_dataIdx;
548
549 if (val)
550 { // if high received then look at log-stop condition
551 ++s_ctr;
552
553 if (s_ctr > c_endBits)
554 { // if stop condition (200 sequenced ones) meets, output on uart
555 uint16_t i;
556
557 for (i = 0; i < c_startcycles; ++i)
558 {
559 irmp_uart_putc ('0'); // the ignored starting zeros
560 }
561
562 for (i = 0;i < (s_dataIdx - c_endBits + 20) / 8; ++i) // transform bitset into uart chars
563 {
564 uint8_t d = s_data[i];
565 uint8_t j;
566
567 for (j = 0;j<8;++j)
568 {
569 irmp_uart_putc ((d & 1) + '0');
570 d >>= 1;
571 }
572 }
573
574 irmp_uart_putc ('\n');
575 s_dataIdx = 0;
576 }
577 }
578 else
579 {
580 s_ctr = 0;
581 }
582 }
583 }
584 }
585
586 #else
587 #define irmp_logIsr(x)
588 #endif
589
590 typedef struct
591 {
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
608 } IRMP_PARAMETER;
609
610 #if IRMP_SUPPORT_SIRCS_PROTOCOL == 1
611
612 static PROGMEM IRMP_PARAMETER sircs_param =
613 {
614 IRMP_SIRCS_PROTOCOL,
615 SIRCS_1_PULSE_LEN_MIN,
616 SIRCS_1_PULSE_LEN_MAX,
617 SIRCS_PAUSE_LEN_MIN,
618 SIRCS_PAUSE_LEN_MAX,
619 SIRCS_0_PULSE_LEN_MIN,
620 SIRCS_0_PULSE_LEN_MAX,
621 SIRCS_PAUSE_LEN_MIN,
622 SIRCS_PAUSE_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,
628 SIRCS_STOP_BIT,
629 SIRCS_LSB
630 };
631
632 #endif
633
634 #if IRMP_SUPPORT_NEC_PROTOCOL == 1
635
636 static PROGMEM IRMP_PARAMETER nec_param =
637 {
638 IRMP_NEC_PROTOCOL,
639 NEC_PULSE_LEN_MIN,
640 NEC_PULSE_LEN_MAX,
641 NEC_1_PAUSE_LEN_MIN,
642 NEC_1_PAUSE_LEN_MAX,
643 NEC_PULSE_LEN_MIN,
644 NEC_PULSE_LEN_MAX,
645 NEC_0_PAUSE_LEN_MIN,
646 NEC_0_PAUSE_LEN_MAX,
647 NEC_ADDRESS_OFFSET,
648 NEC_ADDRESS_OFFSET + NEC_ADDRESS_LEN,
649 NEC_COMMAND_OFFSET,
650 NEC_COMMAND_OFFSET + NEC_COMMAND_LEN,
651 NEC_COMPLETE_DATA_LEN,
652 NEC_STOP_BIT,
653 NEC_LSB
654 };
655
656 #endif
657
658 #if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1
659
660 static PROGMEM IRMP_PARAMETER samsung_param =
661 {
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,
676 SAMSUNG_STOP_BIT,
677 SAMSUNG_LSB
678 };
679
680 #endif
681
682 #if IRMP_SUPPORT_MATSUSHITA_PROTOCOL == 1
683
684 static PROGMEM IRMP_PARAMETER matsushita_param =
685 {
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,
700 MATSUSHITA_STOP_BIT,
701 MATSUSHITA_LSB
702 };
703
704 #endif
705
706 #if IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1
707
708 static PROGMEM IRMP_PARAMETER kaseikyo_param =
709 {
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,
724 KASEIKYO_STOP_BIT,
725 KASEIKYO_LSB
726 };
727
728 #endif
729
730 #if IRMP_SUPPORT_RECS80_PROTOCOL == 1
731
732 static PROGMEM IRMP_PARAMETER recs80_param =
733 {
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,
748 RECS80_STOP_BIT,
749 RECS80_LSB
750 };
751
752 #endif
753
754 #if IRMP_SUPPORT_RC5_PROTOCOL == 1
755
756 static PROGMEM IRMP_PARAMETER rc5_param =
757 {
758 IRMP_RC5_PROTOCOL,
759 RC5_BIT_LEN_MIN,
760 RC5_BIT_LEN_MAX,
761 RC5_BIT_LEN_MIN,
762 RC5_BIT_LEN_MAX,
763 1, // tricky: use this as stop bit length
764 1,
765 1,
766 1,
767 RC5_ADDRESS_OFFSET,
768 RC5_ADDRESS_OFFSET + RC5_ADDRESS_LEN,
769 RC5_COMMAND_OFFSET,
770 RC5_COMMAND_OFFSET + RC5_COMMAND_LEN,
771 RC5_COMPLETE_DATA_LEN,
772 RC5_STOP_BIT,
773 RC5_LSB
774 };
775
776 #endif
777
778 #if IRMP_SUPPORT_DENON_PROTOCOL == 1
779
780 static PROGMEM IRMP_PARAMETER denon_param =
781 {
782 IRMP_DENON_PROTOCOL,
783 DENON_PULSE_LEN_MIN,
784 DENON_PULSE_LEN_MAX,
785 DENON_1_PAUSE_LEN_MIN,
786 DENON_1_PAUSE_LEN_MAX,
787 DENON_PULSE_LEN_MIN,
788 DENON_PULSE_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,
796 DENON_STOP_BIT,
797 DENON_LSB
798 };
799
800 #endif
801
802 #if IRMP_SUPPORT_RC6_PROTOCOL == 1
803
804 static PROGMEM IRMP_PARAMETER rc6_param =
805 {
806 IRMP_RC6_PROTOCOL,
807 RC6_BIT_LEN_MIN,
808 RC6_BIT_LEN_MAX,
809 RC6_BIT_LEN_MIN,
810 RC6_BIT_LEN_MAX,
811 1, // tricky: use this as stop bit length
812 1,
813 1,
814 1,
815 RC6_ADDRESS_OFFSET,
816 RC6_ADDRESS_OFFSET + RC6_ADDRESS_LEN,
817 RC6_COMMAND_OFFSET,
818 RC6_COMMAND_OFFSET + RC6_COMMAND_LEN,
819 RC6_COMPLETE_DATA_LEN_SHORT,
820 RC6_STOP_BIT,
821 RC6_LSB
822 };
823
824 #endif
825
826 #if IRMP_SUPPORT_RECS80EXT_PROTOCOL == 1
827
828 static PROGMEM IRMP_PARAMETER recs80ext_param =
829 {
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,
844 RECS80EXT_STOP_BIT,
845 RECS80EXT_LSB
846 };
847
848 #endif
849
850 #if IRMP_SUPPORT_RECS80EXT_PROTOCOL == 1
851
852 static PROGMEM IRMP_PARAMETER nubert_param =
853 {
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,
868 NUBERT_STOP_BIT,
869 NUBERT_LSB
870 };
871
872 #endif
873
874 static uint8_t irmp_bit; // current bit position
875 static IRMP_PARAMETER irmp_param;
876
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;
883
884 #ifdef DEBUG
885 static uint8_t IRMP_PIN;
886 #endif
887
888 /*---------------------------------------------------------------------------------------------------------------------------------------------------
889 * Initialize IRMP decoder
890 * @details Configures IRMP input pin
891 *---------------------------------------------------------------------------------------------------------------------------------------------------
892 */
893 #ifndef DEBUG
894 void
895 irmp_init (void)
896 {
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
901
902 #if IRMP_LOGGING == 1
903 irmp_uart_init ();
904 #endif
905 }
906 #endif
907 /*---------------------------------------------------------------------------------------------------------------------------------------------------
908 * Get IRMP data
909 * @details gets decoded IRMP data
910 * @param pointer in order to store IRMP data
911 * @return TRUE: successful, FALSE: failed
912 *---------------------------------------------------------------------------------------------------------------------------------------------------
913 */
914 uint8_t
915 irmp_get_data (IRMP_DATA * irmp_data_p)
916 {
917 uint8_t rtc = FALSE;
918
919 if (irmp_ir_detected)
920 {
921 switch (irmp_protocol)
922 {
923 #if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1
924 case IRMP_SAMSUNG_PROTOCOL:
925 if ((irmp_command >> 8) == (~irmp_command & 0x00FF))
926 {
927 irmp_command &= 0xff;
928 irmp_command |= irmp_id << 8;
929 rtc = TRUE;
930 }
931 break;
932 #endif
933 #if IRMP_SUPPORT_NEC_PROTOCOL == 1
934 case IRMP_NEC_PROTOCOL:
935 if ((irmp_command >> 8) == (~irmp_command & 0x00FF))
936 {
937 irmp_command &= 0xff;
938 rtc = TRUE;
939 }
940 else if ((irmp_command & 0xFF00) == 0xD100)
941 {
942 DEBUG_PRINTF ("Switching to APPLE protocol\n");
943 irmp_protocol = IRMP_APPLE_PROTOCOL;
944 irmp_command &= 0xff;
945 rtc = TRUE;
946 }
947 break;
948 #endif
949 default:
950 rtc = TRUE;
951 }
952
953 if (rtc)
954 {
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;
959 irmp_command = 0;
960 irmp_address = 0;
961 irmp_flags = 0;
962 }
963
964 irmp_ir_detected = FALSE;
965 }
966
967 return rtc;
968 }
969
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)
975 #endif
976
977 static uint8_t irmp_bit; // current bit position
978
979 /*---------------------------------------------------------------------------------------------------------------------------------------------------
980 * store bit
981 * @details store bit in temp address or temp command
982 * @param value to store: 0 or 1
983 *---------------------------------------------------------------------------------------------------------------------------------------------------
984 */
985 static void
986 irmp_store_bit (uint8_t value)
987 {
988 if (irmp_bit >= irmp_param.address_offset && irmp_bit < irmp_param.address_end)
989 {
990 if (irmp_param.lsb_first)
991 {
992 irmp_tmp_address |= (((uint16_t) (value)) << (irmp_bit - irmp_param.address_offset)); // CV wants cast
993 }
994 else
995 {
996 irmp_tmp_address <<= 1;
997 irmp_tmp_address |= value;
998 }
999 }
1000 else if (irmp_bit >= irmp_param.command_offset && irmp_bit < irmp_param.command_end)
1001 {
1002 if (irmp_param.lsb_first)
1003 {
1004 irmp_tmp_command |= (((uint16_t) (value)) << (irmp_bit - irmp_param.command_offset)); // CV wants cast
1005 }
1006 else
1007 {
1008 irmp_tmp_command <<= 1;
1009 irmp_tmp_command |= value;
1010 }
1011 }
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)
1014 {
1015 irmp_tmp_id |= (((uint16_t) (value)) << (irmp_bit - SAMSUNG_ID_OFFSET)); // store with LSB first
1016 }
1017 #endif
1018 irmp_bit++;
1019 }
1020
1021 /*---------------------------------------------------------------------------------------------------------------------------------------------------
1022 * ISR routine
1023 * @details ISR routine, called 10000 times per second
1024 *---------------------------------------------------------------------------------------------------------------------------------------------------
1025 */
1026 void
1027 irmp_ISR (void)
1028 {
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
1039 #endif
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
1042 #endif
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
1046 #endif
1047 uint8_t irmp_input; // input value
1048
1049 irmp_input = input(IRMP_PIN);
1050
1051 irmp_logIsr(irmp_input); // log ir signal, if IRMP_LOGGING defined
1052
1053 if (! irmp_ir_detected) // ir code already detected?
1054 { // no...
1055 if (! irmp_start_bit_detected) // start bit detected?
1056 { // no...
1057 if (!irmp_input) // receiving burst?
1058 { // yes...
1059 irmp_pulse_time++; // increment counter
1060 }
1061 else
1062 { // no...
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;
1067 wait_for_space = 0;
1068 irmp_tmp_command = 0;
1069 irmp_tmp_address = 0;
1070 irmp_bit = 0xff;
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!
1074 #endif
1075 }
1076 else
1077 {
1078 repetition_counter++;
1079 }
1080 }
1081 }
1082 else
1083 {
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?
1087 { // yes
1088 irmp_pause_time++; // increment counter
1089
1090 if (irmp_pause_time > IRMP_TIMEOUT) // timeout?
1091 { // yes...
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;
1096 }
1097 }
1098 else
1099 { // receiving first data pulse!
1100 DEBUG_PRINTF ("start-bit: pulse = %d, pause = %d\n", irmp_pulse_time, irmp_pause_time);
1101
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)
1105 { // it's SIRCS
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));
1110 }
1111 else
1112 #endif // IRMP_SUPPORT_SIRCS_PROTOCOL == 1
1113
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)))
1118 { // it's NEC
1119 if (irmp_pause_time <= NEC_REPEAT_START_BIT_PAUSE_LEN_MAX)
1120 {
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);
1124 }
1125 else
1126 {
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);
1130 }
1131
1132 memcpy_P (&irmp_param, &nec_param, sizeof (IRMP_PARAMETER));
1133
1134 if (irmp_pause_time <= NEC_REPEAT_START_BIT_PAUSE_LEN_MAX)
1135 {
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;
1141 }
1142 }
1143 else
1144 #endif // IRMP_SUPPORT_NEC_PROTOCOL == 1
1145
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)
1149 { // it's SAMSUNG
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));
1154 }
1155 else
1156 #endif // IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1
1157
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));
1166 }
1167 else
1168 #endif // IRMP_SUPPORT_MATSUSHITA_PROTOCOL == 1
1169
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)
1173 { // it's KASEIKYO
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));
1178 }
1179 else
1180 #endif // IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1
1181
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)
1185 { // it's RECS80
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));
1190 }
1191 else
1192 #endif // IRMP_SUPPORT_RECS80_PROTOCOL == 1
1193
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)))
1199 { // it's RC5
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;
1205
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))
1208 {
1209 rc5_last_value = 0;
1210 rc5_cmd_bit6 = 1<<6;
1211 }
1212 else
1213 {
1214 rc5_last_value = 1;
1215 }
1216 }
1217 else
1218 #endif // IRMP_SUPPORT_RC5_PROTOCOL == 1
1219
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)))
1224 { // it's DENON
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));
1230 }
1231 else
1232 #endif // IRMP_SUPPORT_DENON_PROTOCOL == 1
1233
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)
1237 { // it's RC6
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));
1242 rc5_last_pause = 0;
1243 rc5_last_value = 0;
1244 }
1245 else
1246 #endif // IRMP_SUPPORT_RC6_PROTOCOL == 1
1247
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)
1251 { // it's RECS80EXT
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));
1256 }
1257 else
1258 #endif // IRMP_SUPPORT_RECS80EXT_PROTOCOL == 1
1259
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)
1263 { // it's NUBERT
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));
1268 }
1269 else
1270 #endif // IRMP_SUPPORT_NUBERT_PROTOCOL == 1
1271
1272 {
1273 DEBUG_PRINTF ("protocol = UNKNOWN\n");
1274 irmp_start_bit_detected = 0; // wait for another start bit...
1275 }
1276
1277 if (irmp_start_bit_detected)
1278 {
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)
1282 {
1283 DEBUG_PRINTF ("pulse_toggle = %2d - %2d\n", RC6_TOGGLE_BIT_LEN_MIN, RC6_TOGGLE_BIT_LEN_MAX);
1284 }
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);
1291 }
1292
1293 irmp_bit = 0;
1294
1295 #if IRMP_SUPPORT_RC5_PROTOCOL == 1
1296 if (irmp_param.protocol == IRMP_RC5_PROTOCOL)
1297 {
1298 if (irmp_pause_time > RC5_START_BIT_LEN_MAX && irmp_pause_time <= 2 * RC5_START_BIT_LEN_MAX)
1299 {
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');
1303 irmp_store_bit (1);
1304 }
1305 else if (! rc5_last_value)
1306 {
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');
1310 irmp_store_bit (0);
1311 }
1312 }
1313 else
1314 #endif // IRMP_SUPPORT_RC5_PROTOCOL == 1
1315
1316 #if IRMP_SUPPORT_DENON_PROTOCOL == 1
1317 if (irmp_param.protocol == IRMP_DENON_PROTOCOL)
1318 {
1319 DEBUG_PRINTF ("[bit %2d: pulse = %2d, pause = %2d] ", irmp_bit, irmp_pulse_time, irmp_pause_time);
1320
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');
1325 irmp_store_bit (1);
1326 }
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');
1331 irmp_store_bit (0);
1332 }
1333 }
1334 #endif // IRMP_SUPPORT_DENON_PROTOCOL == 1
1335
1336 irmp_pulse_time = 1; // set counter to 1, not 0
1337 irmp_pause_time = 0;
1338 wait_for_start_space = 0;
1339 }
1340 }
1341 else if (wait_for_space) // the data section....
1342 { // counting the time of darkness....
1343 uint8_t got_light = FALSE;
1344
1345 if (irmp_input) // still dark?
1346 { // yes...
1347 if (irmp_bit == irmp_param.complete_len && irmp_param.stop_bit == 1)
1348 {
1349 if (irmp_pulse_time >= irmp_param.pulse_0_len_min && irmp_pulse_time <= irmp_param.pulse_0_len_max)
1350 {
1351 #ifdef DEBUG
1352 if (irmp_param.protocol != IRMP_RC5_PROTOCOL)
1353 {
1354 DEBUG_PRINTF ("stop bit detected\n");
1355 }
1356 #endif
1357 irmp_param.stop_bit = 0;
1358 }
1359 else
1360 {
1361 DEBUG_PRINTF ("stop bit timing wrong\n");
1362
1363 irmp_start_bit_detected = 0; // wait for another start bit...
1364 irmp_pulse_time = 0;
1365 irmp_pause_time = 0;
1366 }
1367 }
1368 else
1369 {
1370 irmp_pause_time++; // increment counter
1371
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
1381 }
1382 else
1383 #endif
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
1390 }
1391 else
1392 #endif
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
1399 }
1400 else
1401 #endif
1402 if (irmp_pause_time > IRMP_TIMEOUT) // timeout?
1403 { // yes...
1404 if (irmp_bit == irmp_param.complete_len - 1 && irmp_param.stop_bit == 0)
1405 {
1406 irmp_bit++;
1407 }
1408 else
1409 {
1410 DEBUG_PRINTF ("error 2: pause %d after data bit %d too long\n", irmp_pause_time, irmp_bit);
1411
1412 irmp_start_bit_detected = 0; // wait for another start bit...
1413 irmp_pulse_time = 0;
1414 irmp_pause_time = 0;
1415 }
1416 }
1417 }
1418 }
1419 else
1420 { // got light now!
1421 got_light = TRUE;
1422 }
1423
1424 if (got_light)
1425 {
1426 DEBUG_PRINTF ("[bit %2d: pulse = %2d, pause = %2d] ", irmp_bit, irmp_pulse_time, irmp_pause_time);
1427
1428 #if IRMP_SUPPORT_RC5_PROTOCOL == 1
1429 if (irmp_param.protocol == IRMP_RC5_PROTOCOL) // special rc5 decoder
1430 {
1431 if (irmp_pulse_time > RC5_BIT_LEN_MAX && irmp_pulse_time <= 2 * RC5_BIT_LEN_MAX)
1432 {
1433 DEBUG_PUTCHAR ('1');
1434 irmp_store_bit (1);
1435 DEBUG_PUTCHAR ('0');
1436 DEBUG_PUTCHAR ('\n');
1437 irmp_store_bit (0);
1438 rc5_last_value = 0;
1439 }
1440
1441 else // if (irmp_pulse_time >= RC5_BIT_LEN_MIN && irmp_pulse_time <= RC5_BIT_LEN_MAX)
1442 {
1443 uint8_t rc5_value;
1444
1445 if (rc5_last_pause > RC5_BIT_LEN_MAX && rc5_last_pause <= 2 * RC5_BIT_LEN_MAX)
1446 {
1447 rc5_value = rc5_last_value ? 0 : 1;
1448 rc5_last_value = rc5_value;
1449 }
1450 else
1451 {
1452 rc5_value = rc5_last_value;
1453 }
1454
1455 DEBUG_PUTCHAR (rc5_value + '0');
1456 DEBUG_PUTCHAR ('\n');
1457 irmp_store_bit (rc5_value);
1458 }
1459
1460 rc5_last_pause = irmp_pause_time;
1461 wait_for_space = 0;
1462 }
1463 else
1464 #endif
1465
1466 #if IRMP_SUPPORT_RC6_PROTOCOL == 1
1467 if (irmp_param.protocol == IRMP_RC6_PROTOCOL) // special rc6 decoder
1468 {
1469 switch (irmp_bit)
1470 { // handle toggle bit, which is 2 times longer than other bits
1471 case 3:
1472 case 4:
1473 case 5:
1474 if (irmp_pulse_time > RC6_TOGGLE_BIT_LEN_MAX && irmp_pause_time > RC6_TOGGLE_BIT_LEN_MAX)
1475 {
1476 DEBUG_PUTCHAR ('1');
1477 irmp_store_bit (1);
1478 }
1479
1480 DEBUG_PUTCHAR ('0');
1481 irmp_store_bit (0);
1482 rc5_last_value = 0;
1483 DEBUG_PUTCHAR ('\n');
1484 break;
1485
1486 default:
1487 if (irmp_pulse_time > RC6_BIT_LEN_MAX && irmp_pulse_time <= 2 * RC6_BIT_LEN_MAX)
1488 {
1489 DEBUG_PUTCHAR ('0');
1490 irmp_store_bit (0);
1491 DEBUG_PUTCHAR ('1');
1492 DEBUG_PUTCHAR ('\n');
1493 irmp_store_bit (1);
1494 rc5_last_value = 1;
1495 }
1496 else // if (irmp_pulse_time >= RC6_BIT_LEN_MIN && irmp_pulse_time <= RC6_BIT_LEN_MAX)
1497 {
1498 uint8_t rc5_value;
1499
1500 if (rc5_last_pause > RC6_BIT_LEN_MAX && rc5_last_pause <= 2 * RC6_BIT_LEN_MAX)
1501 {
1502 rc5_value = rc5_last_value ? 0 : 1;
1503 rc5_last_value = rc5_value;
1504 }
1505 else
1506 {
1507 rc5_value = rc5_last_value;
1508 }
1509
1510 if (irmp_bit == 1 && rc5_value == 0)
1511 {
1512 irmp_param.complete_len = RC6_COMPLETE_DATA_LEN_LONG;
1513 }
1514
1515 DEBUG_PUTCHAR (rc5_value + '0');
1516 DEBUG_PUTCHAR ('\n');
1517 irmp_store_bit (rc5_value);
1518 }
1519
1520 rc5_last_pause = irmp_pause_time;
1521 break;
1522 } // switch
1523
1524 wait_for_space = 0;
1525 }
1526 else
1527 #endif
1528
1529 #if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1
1530 if (irmp_param.protocol == IRMP_SAMSUNG_PROTOCOL && irmp_bit == 16) // Samsung: 16th bit
1531 {
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)
1534 {
1535 DEBUG_PRINTF ("SYNC\n");
1536 wait_for_space = 0;
1537 irmp_tmp_id = 0;
1538 irmp_bit++;
1539 }
1540 else if (irmp_pulse_time >= SAMSUNG_PULSE_LEN_MIN && irmp_pulse_time <= SAMSUNG_PULSE_LEN_MAX)
1541 {
1542 if (irmp_pause_time >= SAMSUNG_1_PAUSE_LEN_MIN && irmp_pause_time <= SAMSUNG_1_PAUSE_LEN_MAX)
1543 {
1544 DEBUG_PUTCHAR ('1');
1545 DEBUG_PUTCHAR ('\n');
1546 irmp_store_bit (1);
1547 wait_for_space = 0;
1548 }
1549 else
1550 {
1551 DEBUG_PUTCHAR ('0');
1552 DEBUG_PUTCHAR ('\n');
1553 irmp_store_bit (0);
1554 wait_for_space = 0;
1555 }
1556
1557 DEBUG_PRINTF ("Switching to SAMSUNG32 protocol\n");
1558
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;
1563 }
1564 else
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;
1569 }
1570
1571 irmp_pulse_time = 1; // set counter to 1, not 0
1572 }
1573 else
1574 #endif // IRMP_SUPPORT_SAMSUNG_PROTOCOL
1575
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');
1581 irmp_store_bit (1);
1582 wait_for_space = 0;
1583 }
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');
1589 irmp_store_bit (0);
1590 wait_for_space = 0;
1591 }
1592 else
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;
1597 }
1598
1599 irmp_pulse_time = 1; // set counter to 1, not 0
1600 }
1601 }
1602 else
1603 { // counting the pulse length ...
1604 if (!irmp_input) // still light?
1605 { // yes...
1606 irmp_pulse_time++; // increment counter
1607 }
1608 else
1609 { // now it's dark!
1610 wait_for_space = 1; // let's count the time (see above)
1611 irmp_pause_time = 1; // set pause counter to 1, not 0
1612 }
1613 }
1614
1615 if (irmp_bit == irmp_param.complete_len && irmp_param.stop_bit == 0) // enough bits received?
1616 {
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)
1622 {
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;
1626 }
1627 else
1628 {
1629 DEBUG_PRINTF ("code detected, length = %d\n", irmp_bit);
1630 irmp_ir_detected = TRUE;
1631
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
1636 {
1637 irmp_tmp_command = last_irmp_denon_command; // use command received before!
1638
1639 irmp_protocol = irmp_param.protocol; // store protocol
1640 irmp_address = irmp_tmp_address; // store address
1641 irmp_command = irmp_tmp_command ; // store command
1642 }
1643 else
1644 {
1645 DEBUG_PRINTF ("waiting for inverted command repetition\n");
1646 irmp_ir_detected = FALSE;
1647 last_irmp_denon_command = irmp_tmp_command;
1648 }
1649 }
1650 else
1651 #endif // IRMP_SUPPORT_DENON_PROTOCOL
1652
1653 #if IRMP_SUPPORT_NEC_PROTOCOL == 1
1654 if (irmp_param.protocol == IRMP_NEC_PROTOCOL && irmp_bit == 0) // repetition frame
1655 {
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;
1660 }
1661 else
1662 #endif // IRMP_SUPPORT_NEC_PROTOCOL
1663 {
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
1668 #endif
1669
1670 #if IRMP_SUPPORT_RC5_PROTOCOL == 1
1671 irmp_tmp_command |= rc5_cmd_bit6; // store bit 6
1672 #endif
1673 irmp_command = irmp_tmp_command; // store command
1674
1675 #if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1
1676 irmp_id = irmp_tmp_id;
1677 #endif
1678 }
1679 }
1680
1681 if (irmp_ir_detected)
1682 {
1683 if (last_irmp_command == irmp_command &&
1684 last_irmp_address == irmp_address &&
1685 repetition_counter < IRMP_REPETITION_TIME)
1686 {
1687 irmp_flags |= IRMP_FLAG_REPETITION;
1688 }
1689
1690 last_irmp_address = irmp_tmp_address; // store as last address, too
1691 last_irmp_command = irmp_tmp_command; // store as last command, too
1692
1693 repetition_counter = 0;
1694 }
1695
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;
1700 }
1701 }
1702 }
1703 }
1704
1705 #ifdef DEBUG
1706
1707 // main function - for unix/linux + windows only!
1708 // AVR: see main.c!
1709 // Compile it under linux with:
1710 // cc irmp.c -o irmp
1711 //
1712 // usage: ./irmp [-v|-s|-a] < file
1713
1714 int
1715 main (int argc, char ** argv)
1716 {
1717 int i;
1718 int verbose = FALSE;
1719 int analyze = FALSE;
1720 int ch;
1721 int last_ch = 0;
1722 int pulse = 0;
1723 int pause = 0;
1724
1725 int min_pulse_long = 100000;
1726 int max_pulse_long = 0;
1727 int sum_pulses_long = 0;
1728 int n_pulses_long = 0;
1729
1730 int min_pulse_short = 100000;
1731 int max_pulse_short = 0;
1732 int sum_pulses_short = 0;
1733 int n_pulses_short = 0;
1734
1735 int min_pause_long = 100000;
1736 int max_pause_long = 0;
1737 int sum_pauses_long = 0;
1738 int n_pauses_long = 0;
1739
1740 int min_pause_short = 100000;
1741 int max_pause_short = 0;
1742 int sum_pauses_short = 0;
1743 int n_pauses_short = 0;
1744
1745 int min_start_pulse = 100000;
1746 int max_start_pulse = 0;
1747 int sum_start_pulses = 0;
1748 int n_start_pulses = 0;
1749
1750 int min_start_pause = 100000;
1751 int max_start_pause = 0;
1752 int sum_start_pauses = 0;
1753 int n_start_pauses = 0;
1754
1755 int first_pulse = TRUE;
1756 int first_pause = TRUE;
1757
1758 IRMP_DATA irmp_data;
1759
1760 if (argc == 2)
1761 {
1762 if (! strcmp (argv[1], "-v"))
1763 {
1764 verbose = TRUE;
1765 }
1766 else if (! strcmp (argv[1], "-a"))
1767 {
1768 analyze = TRUE;
1769 verbose = TRUE;
1770 }
1771 else if (! strcmp (argv[1], "-s"))
1772 {
1773 silent = TRUE;
1774 }
1775 }
1776
1777 IRMP_PIN = 0xFF;
1778
1779 while ((ch = getchar ()) != EOF)
1780 {
1781 if (ch == '_' || ch == '0')
1782 {
1783 if (last_ch != ch)
1784 {
1785 if (verbose && pause > 0)
1786 {
1787 printf ("pause: %d\n", pause);
1788
1789 if (first_pause)
1790 {
1791 if (min_start_pause > pause)
1792 {
1793 min_start_pause = pause;
1794 }
1795 if (max_start_pause < pause)
1796 {
1797 max_start_pause = pause;
1798 }
1799 n_start_pauses++;
1800 sum_start_pauses += pause;
1801 first_pause = FALSE;
1802 }
1803 else
1804 {
1805 if (pause >= 10)
1806 {
1807 if (pause > 100) // perhaps repetition frame follows
1808 {
1809 first_pulse = TRUE;
1810 first_pause = TRUE;
1811 }
1812 else
1813 {
1814 if (min_pause_long > pause)
1815 {
1816 min_pause_long = pause;
1817 }
1818 if (max_pause_long < pause)
1819 {
1820 max_pause_long = pause;
1821 }
1822 n_pauses_long++;
1823 sum_pauses_long += pause;
1824 }
1825 }
1826 else
1827 {
1828 if (min_pause_short > pause)
1829 {
1830 min_pause_short = pause;
1831 }
1832 if (max_pause_short < pause)
1833 {
1834 max_pause_short = pause;
1835 }
1836 n_pauses_short++;
1837 sum_pauses_short += pause;
1838 }
1839 }
1840 }
1841 pause = 0;
1842 }
1843 pulse++;
1844 IRMP_PIN = 0x00;
1845 }
1846 else if (ch == 0xaf || ch == '-' || ch == '1')
1847 {
1848 if (last_ch != ch)
1849 {
1850 if (verbose)
1851 {
1852 printf ("pulse: %d ", pulse);
1853
1854 if (first_pulse)
1855 {
1856 if (min_start_pulse > pulse)
1857 {
1858 min_start_pulse = pulse;
1859 }
1860 if (max_start_pulse < pulse)
1861 {
1862 max_start_pulse = pulse;
1863 }
1864 n_start_pulses++;
1865 sum_start_pulses += pulse;
1866 first_pulse = FALSE;
1867 }
1868 else
1869 {
1870 if (pulse >= 10)
1871 {
1872 if (min_pulse_long > pulse)
1873 {
1874 min_pulse_long = pulse;
1875 }
1876 if (max_pulse_long < pulse)
1877 {
1878 max_pulse_long = pulse;
1879 }
1880 n_pulses_long++;
1881 sum_pulses_long += pulse;
1882 }
1883 else
1884 {
1885 if (min_pulse_short > pulse)
1886 {
1887 min_pulse_short = pulse;
1888 }
1889 if (max_pulse_short < pulse)
1890 {
1891 max_pulse_short = pulse;
1892 }
1893 n_pulses_short++;
1894 sum_pulses_short += pulse;
1895 }
1896 }
1897 }
1898 pulse = 0;
1899 }
1900 pause++;
1901 IRMP_PIN = 0xff;
1902 }
1903 else if (ch == '\n')
1904 {
1905 IRMP_PIN = 0xff;
1906
1907 if (verbose && pause > 0)
1908 {
1909 printf ("pause: %d\n", pause);
1910 }
1911 pause = 0;
1912
1913 if (! analyze)
1914 {
1915 for (i = 0; i < 8000; i++) // newline: long pause of 800 msec
1916 {
1917 irmp_ISR ();
1918 }
1919 }
1920 first_pulse = TRUE;
1921 first_pause = TRUE;
1922 }
1923 else if (ch == '#')
1924 {
1925 puts ("-------------------------------------------------------------------");
1926 putchar (ch);
1927
1928 while ((ch = getchar()) != '\n' && ch != EOF)
1929 {
1930 if (ch != '\r') // ignore CR in DOS/Windows files
1931 {
1932 putchar (ch);
1933 }
1934 }
1935 putchar ('\n');
1936 }
1937
1938 last_ch = ch;
1939
1940 if (! analyze)
1941 {
1942 irmp_ISR ();
1943 }
1944
1945 if (irmp_get_data (&irmp_data))
1946 {
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);
1949 }
1950 }
1951
1952 if (analyze)
1953 {
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)
1960 {
1961 printf ("average start pulse length: %d usec\n", ((F_INTERRUPTS * sum_start_pulses) / n_start_pulses) / 100);
1962 }
1963 putchar ('\n');
1964 printf ("number of start pauses: %d\n", n_start_pauses);
1965 if (n_start_pauses > 0)
1966 {
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);
1970 }
1971 putchar ('\n');
1972 printf ("number of long pulses: %d\n", n_pulses_long);
1973 if (n_pulses_long > 0)
1974 {
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);
1978 }
1979 putchar ('\n');
1980 printf ("number of short pulses: %d\n", n_pulses_short);
1981 if (n_pulses_short > 0)
1982 {
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);
1986
1987 }
1988 putchar ('\n');
1989 printf ("number of long pauses: %d\n", n_pauses_long);
1990 if (n_pauses_long > 0)
1991 {
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);
1995 }
1996 putchar ('\n');
1997 printf ("number of short pauses: %d\n", n_pauses_short);
1998 if (n_pauses_short > 0)
1999 {
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);
2003 }
2004 }
2005 return 0;
2006 }
2007
2008 #endif // DEBUG