]> cloudbase.mooo.com Git - irmp.git/blob - irmp.c
bugfix in detection of multiple NEC repetitions, added irmpconfig.h
[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 * $Id: irmp.c,v 1.14 2010/03/29 09:33:29 fm Exp $
7 *
8 * ATMEGA88 @ 8 MHz
9 *
10 * Typical manufacturers:
11 *
12 * SIRCS - Sony
13 * NEC - NEC, Yamaha, Canon, Tevion, Harman/Kardon, Hitachi, JVC, Pioneer, Toshiba, Xoro, Orion, and many other Japanese manufacturers
14 * SAMSUNG - Samsung
15 * MATSUSHITA - Matsushita
16 * KASEIKYO - Panasonic, Denon & other Japanese manufacturers (members of "Japan's Association for Electric Home Application")
17 * RECS80 - Philips, Nokia, Thomson, Nordmende, Telefunken, Saba
18 * RC5 - Philips and other European manufacturers
19 * DENON - Denon
20 * RC6 - Philips and other European manufacturers
21 * APPLE - Apple
22 * NUBERT - Nubert Subwoofer System
23 * PANASONIC - Panasonic (older, yet not implemented)
24 *
25 *---------------------------------------------------------------------------------------------------------------------------------------------------
26 *
27 * SIRCS
28 * -----
29 *
30 * frame: 1 start bit + 12-20 data bits + no stop bit
31 * data: 7 command bits + 5 address bits + 0 to 8 additional bits
32 *
33 * start bit: data "0": data "1": stop bit:
34 * -----------------_________ ------_____ ------------______
35 * 2400us 600us 600us 600us 1200us 600 us no stop bit
36 *
37 *---------------------------------------------------------------------------------------------------------------------------------------------------
38 *
39 * NEC + extended NEC
40 * -------------------------
41 *
42 * frame: 1 start bit + 32 data bits + 1 stop bit
43 * data NEC: 8 address bits + 8 inverted address bits + 8 command bits + 8 inverted command bits
44 * data extended NEC: 16 address bits + 8 command bits + 8 inverted command bits
45 *
46 * start bit: data "0": data "1": stop bit:
47 * -----------------_________ ------______ ------________________ ------______....
48 * 9000us 4500us 560us 560us 560us 1690 us 560us
49 *
50 *
51 * Repetition frame:
52 *
53 * -----------------_________------______ .... ~100ms Pause, then repeat
54 * 9000us 2250us 560us
55 *
56 *---------------------------------------------------------------------------------------------------------------------------------------------------
57 *
58 * SAMSUNG
59 * -------
60 *
61 * frame: 1 start bit + 16 data(1) bits + 1 sync bit + additional 20 data(2) bits + 1 stop bit
62 * data(1): 16 address bits
63 * data(2): 4 ID bits + 8 command bits + 8 inverted command bits
64 *
65 * start bit: data "0": data "1": sync bit: stop bit:
66 * ----------______________ ------______ ------________________ ------______________ ------______....
67 * 4500us 4500us 550us 450us 550us 1450us 550us 4500us 550us
68 *
69 *---------------------------------------------------------------------------------------------------------------------------------------------------
70 *
71 * SAMSUNG32
72 * ----------
73 *
74 * frame: 1 start bit + 32 data bits + 1 stop bit
75 * data: 16 address bits + 16 command bits
76 *
77 * start bit: data "0": data "1": stop bit:
78 * ----------______________ ------______ ------________________ ------______....
79 * 4500us 4500us 550us 450us 550us 1450us 550us
80 *
81 *---------------------------------------------------------------------------------------------------------------------------------------------------
82 *
83 * MATSUSHITA
84 * ----------
85 *
86 * frame: 1 start bit + 24 data bits + 1 stop bit
87 * data: 6 custom bits + 6 command bits + 12 address bits
88 *
89 * start bit: data "0": data "1": stop bit:
90 * ----------_________ ------______ ------________________ ------______....
91 * 3488us 3488us 872us 872us 872us 2616us 872us
92 *
93 *---------------------------------------------------------------------------------------------------------------------------------------------------
94 *
95 * KASEIKYO
96 * --------
97 *
98 * frame: 1 start bit + 48 data bits + 1 stop bit
99 * data: 16 manufacturer bits + 4 parity bits + 4 genre1 bits + 4 genre2 bits + 10 command bits + 2 id bits + 8 parity bits
100 *
101 * start bit: data "0": data "1": stop bit:
102 * ----------______ ------______ ------________________ ------______....
103 * 3380us 1690us 423us 423us 423us 1269us 423us
104 *
105 *---------------------------------------------------------------------------------------------------------------------------------------------------
106 *
107 * RECS80
108 * ------
109 *
110 * frame: 2 start bits + 10 data bits + 1 stop bit
111 * data: 1 toggle bit + 3 address bits + 6 command bits
112 *
113 * start bit: data "0": data "1": stop bit:
114 * -----_____________________ -----____________ -----______________ ------_______....
115 * 158us 7432us 158us 4902us 158us 7432us 158us
116 *
117 *---------------------------------------------------------------------------------------------------------------------------------------------------
118 *
119 * RECS80EXT
120 * ---------
121 *
122 * frame: 2 start bits + 11 data bits + 1 stop bit
123 * data: 1 toggle bit + 4 address bits + 6 command bits
124 *
125 * start bit: data "0": data "1": stop bit:
126 * -----_____________________ -----____________ -----______________ ------_______....
127 * 158us 3637us 158us 4902us 158us 7432us 158us
128 *
129 *---------------------------------------------------------------------------------------------------------------------------------------------------
130 *
131 * RC5 + RC5X
132 * ----------
133 *
134 * RC5 frame: 2 start bits + 12 data bits + no stop bit
135 * RC5 data: 1 toggle bit + 5 address bits + 6 command bits
136 * RC5X frame: 1 start bit + 13 data bits + no stop bit
137 * RC5X data: 1 inverted command bit + 1 toggle bit + 5 address bits + 6 command bits
138 *
139 * start bit: data "0": data "1":
140 * ______----- ------______ ______------
141 * 889us 889us 889us 889us 889us 889us
142 *
143 *---------------------------------------------------------------------------------------------------------------------------------------------------
144 *
145 * DENON
146 * -----
147 *
148 * frame: 0 start bits + 16 data bits + stop bit + 65ms pause + 16 inverted data bits + stop bit
149 * data: 5 address bits + 10 command bits
150 *
151 * data "0": data "1":
152 * ------________________ ------______________
153 * 275us 1050us 275us 1900us
154 *
155 *---------------------------------------------------------------------------------------------------------------------------------------------------
156 *
157 * RC6
158 * ---
159 *
160 * RC6 frame: 1 start bit + 1 bit "1" + 3 mode bits + 1 toggle bit + 16 data bits + 2666 µs pause
161 * RC6 data: 8 address bits + 8 command bits
162 *
163 * start bit toggle bit "0": toggle bit "1": data/mode "0": data/mode "1":
164 * ____________------- _______------- -------_______ _______------- -------_______
165 * 2666us 889us 889us 889us 889us 889us 444us 444us 444us 444us
166 *
167 *---------------------------------------------------------------------------------------------------------------------------------------------------
168 *
169 * APPLE
170 * -----
171 *
172 * frame: 1 start bit + 32 data bits + 1 stop bit
173 * data: 16 address bits + 11100000 + 8 command bits
174 *
175 * start bit: data "0": data "1": stop bit:
176 * -----------------_________ ------______ ------________________ ------______....
177 * 9000us 4500us 560us 560us 560us 1690 us 560us
178 *
179 *---------------------------------------------------------------------------------------------------------------------------------------------------
180 *
181 * NUBERT (subwoofer system)
182 * -------------------------
183 *
184 * frame: 1 start bit + 10 data bits + 1 stop bit
185 * data: 0 address bits + 10 command bits ?
186 *
187 * start bit: data "0": data "1": stop bit:
188 * ----------_____ ------______ ------________________ ------______....
189 * 1340us 340us 500us 1300us 1340us 340us 500us
190 *
191 *---------------------------------------------------------------------------------------------------------------------------------------------------
192 *
193 * PANASONIC (older protocol, yet not implemented, see also MATSUSHITA, timing very similar)
194 * -----------------------------------------------------------------------------------------
195 *
196 * frame: 1 start bit + 22 data bits + 1 stop bit
197 * 22 data bits = 5 custom bits + 6 data bits + 5 inverted custom bits + 6 inverted data bits
198 *
199 * European version: T = 456us
200 * USA & Canada version: T = 422us
201 *
202 * start bit: data "0": data "1": stop bit:
203 * 8T 8T 2T 2T 2T 6T 2T
204 * -------------____________ ------_____ ------_____________ ------_______....
205 * 3648us 3648us 912us 912us 912us 2736us 912us (Europe)
206 * 3376us 3376us 844us 844us 844us 2532us 844us (US)
207 *
208 *---------------------------------------------------------------------------------------------------------------------------------------------------
209 *
210 * This program is free software; you can redistribute it and/or modify
211 * it under the terms of the GNU General Public License as published by
212 * the Free Software Foundation; either version 2 of the License, or
213 * (at your option) any later version.
214 *---------------------------------------------------------------------------------------------------------------------------------------------------
215 */
216
217 #if defined(__PCM__) || defined(__PCB__) || defined(__PCH__) // CCS PIC Compiler instead of AVR
218 #define PIC_CCS_COMPILER
219 #endif
220
221 #ifdef unix // test on linux/unix
222 #include <stdio.h>
223 #include <unistd.h>
224 #include <stdlib.h>
225 #include <string.h>
226 #include <inttypes.h>
227
228 #define DEBUG
229 #define PROGMEM
230 #define memcpy_P memcpy
231
232 #else // not unix:
233
234 #ifdef WIN32
235 #include <stdio.h>
236 #include <string.h>
237 typedef unsigned char uint8_t;
238 typedef unsigned short uint16_t;
239 #define DEBUG
240 #define PROGMEM
241 #define memcpy_P memcpy
242
243 #else
244
245 #ifndef CODEVISION
246
247 #ifdef PIC_CCS_COMPILER
248
249 #include <string.h>
250 typedef unsigned int8 uint8_t;
251 typedef unsigned int16 uint16_t;
252 #define PROGMEM
253 #define memcpy_P memcpy
254
255 #else // AVR:
256
257 #include <inttypes.h>
258 #include <stdio.h>
259 #include <string.h>
260 #include <avr/io.h>
261 #include <util/delay.h>
262 #include <avr/pgmspace.h>
263
264 #endif // PIC_CCS_COMPILER
265 #endif // CODEVISION
266
267 #endif // windows
268 #endif // unix
269
270 #include "irmp.h"
271 #include "irmpconfig.h"
272
273 #define IRMP_TIMEOUT 120 // timeout after 12 ms darkness
274 #define IRMP_REPETITION_TIME (uint16_t)(F_INTERRUPTS * 100.0e-3 + 0.5) // autodetect key repetition within 100 msec
275
276 #define MIN_TOLERANCE_10 0.9 // -10%
277 #define MAX_TOLERANCE_10 1.1 // +10%
278
279 #define MIN_TOLERANCE_20 0.8 // -20%
280 #define MAX_TOLERANCE_20 1.2 // +20%
281
282 #define MIN_TOLERANCE_30 0.7 // -30%
283 #define MAX_TOLERANCE_30 1.3 // +30%
284
285 #define MIN_TOLERANCE_40 0.6 // -40%
286 #define MAX_TOLERANCE_40 1.4 // +40%
287
288 #define MIN_TOLERANCE_50 0.5 // -50%
289 #define MAX_TOLERANCE_50 1.5 // +50%
290
291 #define MIN_TOLERANCE_60 0.4 // -60%
292 #define MAX_TOLERANCE_60 1.6 // +60%
293
294 #define SIRCS_START_BIT_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * SIRCS_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5)
295 #define SIRCS_START_BIT_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * SIRCS_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5)
296 #define SIRCS_START_BIT_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * SIRCS_START_BIT_PAUSE_TIME * MIN_TOLERANCE_50 + 0.5)
297 #define SIRCS_START_BIT_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * SIRCS_START_BIT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5)
298 #define SIRCS_1_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * SIRCS_1_PULSE_TIME * MIN_TOLERANCE_20 + 0.5)
299 #define SIRCS_1_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * SIRCS_1_PULSE_TIME * MAX_TOLERANCE_30 + 0.5)
300 #define SIRCS_0_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * SIRCS_0_PULSE_TIME * MIN_TOLERANCE_50 + 0.5)
301 #define SIRCS_0_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * SIRCS_0_PULSE_TIME * MAX_TOLERANCE_50 + 0.5)
302 #define SIRCS_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * SIRCS_PAUSE_TIME * MIN_TOLERANCE_50 + 0.5)
303 #define SIRCS_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * SIRCS_PAUSE_TIME * MAX_TOLERANCE_50 + 0.5)
304
305 #define NEC_START_BIT_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * NEC_START_BIT_PULSE_TIME * MIN_TOLERANCE_40 + 0.5)
306 #define NEC_START_BIT_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * NEC_START_BIT_PULSE_TIME * MAX_TOLERANCE_40 + 0.5)
307 #define NEC_START_BIT_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * NEC_START_BIT_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5)
308 #define NEC_START_BIT_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * NEC_START_BIT_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5)
309 #define NEC_REPEAT_START_BIT_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * NEC_REPEAT_START_BIT_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5)
310 #define NEC_REPEAT_START_BIT_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * NEC_REPEAT_START_BIT_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5)
311 #define NEC_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * NEC_PULSE_TIME * MIN_TOLERANCE_40 + 0.5)
312 #define NEC_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * NEC_PULSE_TIME * MAX_TOLERANCE_40 + 0.5)
313 #define NEC_1_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * NEC_1_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5)
314 #define NEC_1_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * NEC_1_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5)
315 #define NEC_0_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * NEC_0_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5)
316 #define NEC_0_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * NEC_0_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5)
317
318 #define SAMSUNG_START_BIT_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5)
319 #define SAMSUNG_START_BIT_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5)
320 #define SAMSUNG_START_BIT_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5)
321 #define SAMSUNG_START_BIT_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5)
322 #define SAMSUNG_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * SAMSUNG_PULSE_TIME * MIN_TOLERANCE_50 + 0.5)
323 #define SAMSUNG_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * SAMSUNG_PULSE_TIME * MAX_TOLERANCE_50 + 0.5)
324 #define SAMSUNG_1_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * SAMSUNG_1_PAUSE_TIME * MIN_TOLERANCE_50 + 0.5)
325 #define SAMSUNG_1_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * SAMSUNG_1_PAUSE_TIME * MAX_TOLERANCE_50 + 0.5)
326 #define SAMSUNG_0_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * SAMSUNG_0_PAUSE_TIME * MIN_TOLERANCE_50 + 0.5)
327 #define SAMSUNG_0_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * SAMSUNG_0_PAUSE_TIME * MAX_TOLERANCE_50 + 0.5)
328
329 #define MATSUSHITA_START_BIT_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5)
330 #define MATSUSHITA_START_BIT_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5)
331 #define MATSUSHITA_START_BIT_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5)
332 #define MATSUSHITA_START_BIT_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5)
333 #define MATSUSHITA_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * MATSUSHITA_PULSE_TIME * MIN_TOLERANCE_40 + 0.5)
334 #define MATSUSHITA_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * MATSUSHITA_PULSE_TIME * MAX_TOLERANCE_40 + 0.5)
335 #define MATSUSHITA_1_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * MATSUSHITA_1_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5)
336 #define MATSUSHITA_1_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * MATSUSHITA_1_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5)
337 #define MATSUSHITA_0_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * MATSUSHITA_0_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5)
338 #define MATSUSHITA_0_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * MATSUSHITA_0_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5)
339
340 #define KASEIKYO_START_BIT_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PULSE_TIME * MIN_TOLERANCE_30 + 0.5)
341 #define KASEIKYO_START_BIT_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PULSE_TIME * MAX_TOLERANCE_30 + 0.5)
342 #define KASEIKYO_START_BIT_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5)
343 #define KASEIKYO_START_BIT_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5)
344 #define KASEIKYO_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * KASEIKYO_PULSE_TIME * MIN_TOLERANCE_50 + 0.5)
345 #define KASEIKYO_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * KASEIKYO_PULSE_TIME * MAX_TOLERANCE_60 + 0.5)
346 #define KASEIKYO_1_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * KASEIKYO_1_PAUSE_TIME * MIN_TOLERANCE_50 + 0.5)
347 #define KASEIKYO_1_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * KASEIKYO_1_PAUSE_TIME * MAX_TOLERANCE_50 + 0.5)
348 #define KASEIKYO_0_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * KASEIKYO_0_PAUSE_TIME * MIN_TOLERANCE_50 + 0.5)
349 #define KASEIKYO_0_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * KASEIKYO_0_PAUSE_TIME * MAX_TOLERANCE_50 + 0.5)
350
351 #define RECS80_START_BIT_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * RECS80_START_BIT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5)
352 #define RECS80_START_BIT_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * RECS80_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5)
353 #define RECS80_START_BIT_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * RECS80_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5)
354 #define RECS80_START_BIT_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * RECS80_START_BIT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5)
355 #define RECS80_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * RECS80_PULSE_TIME * MIN_TOLERANCE_20 + 0.5)
356 #define RECS80_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * RECS80_PULSE_TIME * MAX_TOLERANCE_20 + 0.5)
357 #define RECS80_1_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * RECS80_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5)
358 #define RECS80_1_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * RECS80_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5)
359 #define RECS80_0_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * RECS80_0_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5)
360 #define RECS80_0_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * RECS80_0_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5)
361
362 #define RC5_START_BIT_LEN_MIN (uint8_t)(F_INTERRUPTS * RC5_BIT_TIME * MIN_TOLERANCE_20 + 0.5)
363 #define RC5_START_BIT_LEN_MAX (uint8_t)(F_INTERRUPTS * RC5_BIT_TIME * MAX_TOLERANCE_20 + 0.5)
364 #define RC5_BIT_LEN_MIN (uint8_t)(F_INTERRUPTS * RC5_BIT_TIME * MIN_TOLERANCE_20 + 0.5)
365 #define RC5_BIT_LEN_MAX (uint8_t)(F_INTERRUPTS * RC5_BIT_TIME * MAX_TOLERANCE_20 + 0.5)
366
367 #define DENON_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * DENON_PULSE_TIME * MIN_TOLERANCE_50 + 0.5)
368 #define DENON_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * DENON_PULSE_TIME * MAX_TOLERANCE_50 + 0.5)
369 #define DENON_1_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * DENON_1_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5)
370 #define DENON_1_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * DENON_1_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5)
371 #define DENON_0_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * DENON_0_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5)
372 #define DENON_0_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * DENON_0_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5)
373
374 #define RC6_START_BIT_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * RC6_START_BIT_PULSE_TIME * MIN_TOLERANCE_30 + 0.5)
375 #define RC6_START_BIT_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * RC6_START_BIT_PULSE_TIME * MAX_TOLERANCE_30 + 0.5)
376 #define RC6_START_BIT_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * RC6_START_BIT_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5)
377 #define RC6_START_BIT_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * RC6_START_BIT_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5)
378 #define RC6_TOGGLE_BIT_LEN_MIN (uint8_t)(F_INTERRUPTS * RC6_TOGGLE_BIT_TIME * MIN_TOLERANCE_20 + 0.5)
379 #define RC6_TOGGLE_BIT_LEN_MAX (uint8_t)(F_INTERRUPTS * RC6_TOGGLE_BIT_TIME * MAX_TOLERANCE_20 + 0.5)
380 #define RC6_BIT_LEN_MIN (uint8_t)(F_INTERRUPTS * RC6_BIT_TIME * MIN_TOLERANCE_30 + 0.5)
381 #define RC6_BIT_LEN_MAX (uint8_t)(F_INTERRUPTS * RC6_BIT_TIME * MAX_TOLERANCE_30 + 0.5)
382
383 #define RECS80EXT_START_BIT_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5)
384 #define RECS80EXT_START_BIT_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5)
385 #define RECS80EXT_START_BIT_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5)
386 #define RECS80EXT_START_BIT_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5)
387 #define RECS80EXT_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * RECS80EXT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5)
388 #define RECS80EXT_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * RECS80EXT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5)
389 #define RECS80EXT_1_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * RECS80EXT_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5)
390 #define RECS80EXT_1_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * RECS80EXT_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5)
391 #define RECS80EXT_0_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * RECS80EXT_0_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5)
392 #define RECS80EXT_0_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * RECS80EXT_0_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5)
393
394 #define NUBERT_START_BIT_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * NUBERT_START_BIT_PULSE_TIME * MIN_TOLERANCE_40 + 0.5)
395 #define NUBERT_START_BIT_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * NUBERT_START_BIT_PULSE_TIME * MAX_TOLERANCE_40 + 0.5)
396 #define NUBERT_START_BIT_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * NUBERT_START_BIT_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5)
397 #define NUBERT_START_BIT_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * NUBERT_START_BIT_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5)
398 #define NUBERT_1_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * NUBERT_1_PULSE_TIME * MIN_TOLERANCE_40 + 0.5)
399 #define NUBERT_1_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * NUBERT_1_PULSE_TIME * MAX_TOLERANCE_40 + 0.5)
400 #define NUBERT_1_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * NUBERT_1_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5)
401 #define NUBERT_1_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * NUBERT_1_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5)
402 #define NUBERT_0_PULSE_LEN_MIN (uint8_t)(F_INTERRUPTS * NUBERT_0_PULSE_TIME * MIN_TOLERANCE_40 + 0.5)
403 #define NUBERT_0_PULSE_LEN_MAX (uint8_t)(F_INTERRUPTS * NUBERT_0_PULSE_TIME * MAX_TOLERANCE_40 + 0.5)
404 #define NUBERT_0_PAUSE_LEN_MIN (uint8_t)(F_INTERRUPTS * NUBERT_0_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5)
405 #define NUBERT_0_PAUSE_LEN_MAX (uint8_t)(F_INTERRUPTS * NUBERT_0_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5)
406
407 #define AUTO_REPETITION_LEN (uint16_t)(F_INTERRUPTS * AUTO_REPETITION_TIME + 0.5) // use uint16_t!
408
409 #ifdef DEBUG
410 #define DEBUG_PUTCHAR(a) { if (! silent) { putchar (a); } }
411 #define DEBUG_PRINTF(...) { if (! silent) { printf (__VA_ARGS__); } }
412 static int silent;
413 #else
414 #define DEBUG_PUTCHAR(a)
415 #define DEBUG_PRINTF(...)
416 #endif
417
418 #if IRMP_LOGGING == 1
419 #define irmp_logIsr(x) irmp_logIr((x) ? 1:0)
420 #define UART_BAUD 9600L
421
422 // calculate real baud rate:
423 #define UBRR_VAL ((F_CPU+UART_BAUD*8)/(UART_BAUD*16)-1) // round
424 #define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) // real baudrate
425
426 #ifdef CODEVISION
427 #if ((BAUD_REAL*1000)/UART_BAUD-1000) > 10
428 # error Error of baud rate of RS232 UARTx is more than 1%. That is too high!
429 #endif
430
431 #else // not CODEVISION
432
433 #define BAUD_ERROR ((BAUD_REAL*1000)/UART_BAUD-1000) // error in promille
434
435 #if ((BAUD_ERROR > 10) || (-BAUD_ERROR < 10))
436 # error Error of baud rate of RS232 UARTx is more than 1%. That is too high!
437 #endif
438
439 #endif // CODEVISION
440
441 /*---------------------------------------------------------------------------------------------------------------------------------------------------
442 * Initialize UART
443 * @details Initializes UART
444 *---------------------------------------------------------------------------------------------------------------------------------------------------
445 */
446 void
447 irmp_uart_init (void)
448 {
449 UCSR0B |= (1<<TXEN0); // activate UART0 TX
450 UBRR0H = UBRR_VAL >> 8; // store baudrate (upper byte)
451 UBRR0L = UBRR_VAL & 0xFF; // store baudrate (lower byte)
452 }
453
454 /*---------------------------------------------------------------------------------------------------------------------------------------------------
455 * Send character
456 * @details Sends character
457 * @param ch character to be transmitted
458 *---------------------------------------------------------------------------------------------------------------------------------------------------
459 */
460 void
461 irmp_uart_putc (unsigned char ch)
462 {
463 while (!(UCSR0A & (1<<UDRE0)))
464 {
465 ;
466 }
467
468 UDR0 = ch;
469 }
470
471 /*---------------------------------------------------------------------------------------------------------------------------------------------------
472 * Log IR signal
473 *---------------------------------------------------------------------------------------------------------------------------------------------------
474 */
475 #define c_startcycles 2 // min count of zeros before start of logging
476 #define c_endBits 1000 // log buffer size
477 #define c_datalen 700 // number of sequenced highbits to detect end
478
479 static void
480 irmp_logIr (uint8_t val)
481 {
482 static uint8_t s_data[c_datalen]; // logging buffer
483 static uint16_t s_dataIdx; // number of written bits
484 static uint8_t s_startcycles; // current number of start-zeros
485 static uint16_t s_ctr; // counts sequenced highbits - to detect end
486
487 if ((val == 0) && (s_startcycles < c_startcycles) && !s_dataIdx) // prevent that single random zeros init logging
488 {
489 ++s_startcycles;
490 }
491 else
492 {
493 s_startcycles = 0;
494
495 if ( (val == 0) // start or continue logging on "0"
496 || ((val == 1) && (s_dataIdx != 0))) // "1" cannot init logging
497 {
498 if (val)
499 { // set or clear bit in bitarray
500 s_data[(s_dataIdx / 8)] |= (1<<(s_dataIdx % 8));
501 }
502 else
503 {
504 s_data[(s_dataIdx / 8)] &= ~(1<<(s_dataIdx % 8));
505 }
506
507 ++s_dataIdx;
508
509 if (val)
510 { // if high received then look at log-stop condition
511 ++s_ctr;
512
513 if (s_ctr > c_endBits)
514 { // if stop condition (200 sequenced ones) meets, output on uart
515 uint16_t i;
516
517 for (i = 0; i < c_startcycles; ++i)
518 {
519 irmp_uart_putc ('0'); // the ignored starting zeros
520 }
521
522 for (i = 0;i < (s_dataIdx - c_endBits + 20) / 8; ++i) // transform bitset into uart chars
523 {
524 uint8_t d = s_data[i];
525 uint8_t j;
526
527 for (j = 0;j<8;++j)
528 {
529 irmp_uart_putc ((d & 1) + '0');
530 d >>= 1;
531 }
532 }
533
534 irmp_uart_putc ('\n');
535 s_dataIdx = 0;
536 }
537 }
538 else
539 {
540 s_ctr = 0;
541 }
542 }
543 }
544 }
545
546 #else
547 #define irmp_logIsr(x)
548 #endif
549
550 typedef struct
551 {
552 uint8_t protocol; // ir protocol
553 uint8_t pulse_1_len_min; // minimum length of pulse with bit value 1
554 uint8_t pulse_1_len_max; // maximum length of pulse with bit value 1
555 uint8_t pause_1_len_min; // minimum length of pause with bit value 1
556 uint8_t pause_1_len_max; // maximum length of pause with bit value 1
557 uint8_t pulse_0_len_min; // minimum length of pulse with bit value 0
558 uint8_t pulse_0_len_max; // maximum length of pulse with bit value 0
559 uint8_t pause_0_len_min; // minimum length of pause with bit value 0
560 uint8_t pause_0_len_max; // maximum length of pause with bit value 0
561 uint8_t address_offset; // address offset
562 uint8_t address_end; // end of address
563 uint8_t command_offset; // command offset
564 uint8_t command_end; // end of command
565 uint8_t complete_len; // complete length of frame
566 uint8_t stop_bit; // flag: frame has stop bit
567 uint8_t lsb_first; // flag: LSB first
568 } IRMP_PARAMETER;
569
570 #if IRMP_SUPPORT_SIRCS_PROTOCOL == 1
571
572 static PROGMEM IRMP_PARAMETER sircs_param =
573 {
574 IRMP_SIRCS_PROTOCOL,
575 SIRCS_1_PULSE_LEN_MIN,
576 SIRCS_1_PULSE_LEN_MAX,
577 SIRCS_PAUSE_LEN_MIN,
578 SIRCS_PAUSE_LEN_MAX,
579 SIRCS_0_PULSE_LEN_MIN,
580 SIRCS_0_PULSE_LEN_MAX,
581 SIRCS_PAUSE_LEN_MIN,
582 SIRCS_PAUSE_LEN_MAX,
583 SIRCS_ADDRESS_OFFSET,
584 SIRCS_ADDRESS_OFFSET + SIRCS_ADDRESS_LEN,
585 SIRCS_COMMAND_OFFSET,
586 SIRCS_COMMAND_OFFSET + SIRCS_COMMAND_LEN,
587 SIRCS_COMPLETE_DATA_LEN,
588 SIRCS_STOP_BIT,
589 SIRCS_LSB
590 };
591
592 #endif
593
594 #if IRMP_SUPPORT_NEC_PROTOCOL == 1
595
596 static PROGMEM IRMP_PARAMETER nec_param =
597 {
598 IRMP_NEC_PROTOCOL,
599 NEC_PULSE_LEN_MIN,
600 NEC_PULSE_LEN_MAX,
601 NEC_1_PAUSE_LEN_MIN,
602 NEC_1_PAUSE_LEN_MAX,
603 NEC_PULSE_LEN_MIN,
604 NEC_PULSE_LEN_MAX,
605 NEC_0_PAUSE_LEN_MIN,
606 NEC_0_PAUSE_LEN_MAX,
607 NEC_ADDRESS_OFFSET,
608 NEC_ADDRESS_OFFSET + NEC_ADDRESS_LEN,
609 NEC_COMMAND_OFFSET,
610 NEC_COMMAND_OFFSET + NEC_COMMAND_LEN,
611 NEC_COMPLETE_DATA_LEN,
612 NEC_STOP_BIT,
613 NEC_LSB
614 };
615
616 #endif
617
618 #if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1
619
620 static PROGMEM IRMP_PARAMETER samsung_param =
621 {
622 IRMP_SAMSUNG_PROTOCOL,
623 SAMSUNG_PULSE_LEN_MIN,
624 SAMSUNG_PULSE_LEN_MAX,
625 SAMSUNG_1_PAUSE_LEN_MIN,
626 SAMSUNG_1_PAUSE_LEN_MAX,
627 SAMSUNG_PULSE_LEN_MIN,
628 SAMSUNG_PULSE_LEN_MAX,
629 SAMSUNG_0_PAUSE_LEN_MIN,
630 SAMSUNG_0_PAUSE_LEN_MAX,
631 SAMSUNG_ADDRESS_OFFSET,
632 SAMSUNG_ADDRESS_OFFSET + SAMSUNG_ADDRESS_LEN,
633 SAMSUNG_COMMAND_OFFSET,
634 SAMSUNG_COMMAND_OFFSET + SAMSUNG_COMMAND_LEN,
635 SAMSUNG_COMPLETE_DATA_LEN,
636 SAMSUNG_STOP_BIT,
637 SAMSUNG_LSB
638 };
639
640 #endif
641
642 #if IRMP_SUPPORT_MATSUSHITA_PROTOCOL == 1
643
644 static PROGMEM IRMP_PARAMETER matsushita_param =
645 {
646 IRMP_MATSUSHITA_PROTOCOL,
647 MATSUSHITA_PULSE_LEN_MIN,
648 MATSUSHITA_PULSE_LEN_MAX,
649 MATSUSHITA_1_PAUSE_LEN_MIN,
650 MATSUSHITA_1_PAUSE_LEN_MAX,
651 MATSUSHITA_PULSE_LEN_MIN,
652 MATSUSHITA_PULSE_LEN_MAX,
653 MATSUSHITA_0_PAUSE_LEN_MIN,
654 MATSUSHITA_0_PAUSE_LEN_MAX,
655 MATSUSHITA_ADDRESS_OFFSET,
656 MATSUSHITA_ADDRESS_OFFSET + MATSUSHITA_ADDRESS_LEN,
657 MATSUSHITA_COMMAND_OFFSET,
658 MATSUSHITA_COMMAND_OFFSET + MATSUSHITA_COMMAND_LEN,
659 MATSUSHITA_COMPLETE_DATA_LEN,
660 MATSUSHITA_STOP_BIT,
661 MATSUSHITA_LSB
662 };
663
664 #endif
665
666 #if IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1
667
668 static PROGMEM IRMP_PARAMETER kaseikyo_param =
669 {
670 IRMP_KASEIKYO_PROTOCOL,
671 KASEIKYO_PULSE_LEN_MIN,
672 KASEIKYO_PULSE_LEN_MAX,
673 KASEIKYO_1_PAUSE_LEN_MIN,
674 KASEIKYO_1_PAUSE_LEN_MAX,
675 KASEIKYO_PULSE_LEN_MIN,
676 KASEIKYO_PULSE_LEN_MAX,
677 KASEIKYO_0_PAUSE_LEN_MIN,
678 KASEIKYO_0_PAUSE_LEN_MAX,
679 KASEIKYO_ADDRESS_OFFSET,
680 KASEIKYO_ADDRESS_OFFSET + KASEIKYO_ADDRESS_LEN,
681 KASEIKYO_COMMAND_OFFSET,
682 KASEIKYO_COMMAND_OFFSET + KASEIKYO_COMMAND_LEN,
683 KASEIKYO_COMPLETE_DATA_LEN,
684 KASEIKYO_STOP_BIT,
685 KASEIKYO_LSB
686 };
687
688 #endif
689
690 #if IRMP_SUPPORT_RECS80_PROTOCOL == 1
691
692 static PROGMEM IRMP_PARAMETER recs80_param =
693 {
694 IRMP_RECS80_PROTOCOL,
695 RECS80_PULSE_LEN_MIN,
696 RECS80_PULSE_LEN_MAX,
697 RECS80_1_PAUSE_LEN_MIN,
698 RECS80_1_PAUSE_LEN_MAX,
699 RECS80_PULSE_LEN_MIN,
700 RECS80_PULSE_LEN_MAX,
701 RECS80_0_PAUSE_LEN_MIN,
702 RECS80_0_PAUSE_LEN_MAX,
703 RECS80_ADDRESS_OFFSET,
704 RECS80_ADDRESS_OFFSET + RECS80_ADDRESS_LEN,
705 RECS80_COMMAND_OFFSET,
706 RECS80_COMMAND_OFFSET + RECS80_COMMAND_LEN,
707 RECS80_COMPLETE_DATA_LEN,
708 RECS80_STOP_BIT,
709 RECS80_LSB
710 };
711
712 #endif
713
714 #if IRMP_SUPPORT_RC5_PROTOCOL == 1
715
716 static PROGMEM IRMP_PARAMETER rc5_param =
717 {
718 IRMP_RC5_PROTOCOL,
719 RC5_BIT_LEN_MIN,
720 RC5_BIT_LEN_MAX,
721 RC5_BIT_LEN_MIN,
722 RC5_BIT_LEN_MAX,
723 1, // tricky: use this as stop bit length
724 1,
725 1,
726 1,
727 RC5_ADDRESS_OFFSET,
728 RC5_ADDRESS_OFFSET + RC5_ADDRESS_LEN,
729 RC5_COMMAND_OFFSET,
730 RC5_COMMAND_OFFSET + RC5_COMMAND_LEN,
731 RC5_COMPLETE_DATA_LEN,
732 RC5_STOP_BIT,
733 RC5_LSB
734 };
735
736 #endif
737
738 #if IRMP_SUPPORT_DENON_PROTOCOL == 1
739
740 static PROGMEM IRMP_PARAMETER denon_param =
741 {
742 IRMP_DENON_PROTOCOL,
743 DENON_PULSE_LEN_MIN,
744 DENON_PULSE_LEN_MAX,
745 DENON_1_PAUSE_LEN_MIN,
746 DENON_1_PAUSE_LEN_MAX,
747 DENON_PULSE_LEN_MIN,
748 DENON_PULSE_LEN_MAX,
749 DENON_0_PAUSE_LEN_MIN,
750 DENON_0_PAUSE_LEN_MAX,
751 DENON_ADDRESS_OFFSET,
752 DENON_ADDRESS_OFFSET + DENON_ADDRESS_LEN,
753 DENON_COMMAND_OFFSET,
754 DENON_COMMAND_OFFSET + DENON_COMMAND_LEN,
755 DENON_COMPLETE_DATA_LEN,
756 DENON_STOP_BIT,
757 DENON_LSB
758 };
759
760 #endif
761
762 #if IRMP_SUPPORT_RC6_PROTOCOL == 1
763
764 static PROGMEM IRMP_PARAMETER rc6_param =
765 {
766 IRMP_RC6_PROTOCOL,
767 RC6_BIT_LEN_MIN,
768 RC6_BIT_LEN_MAX,
769 RC6_BIT_LEN_MIN,
770 RC6_BIT_LEN_MAX,
771 1, // tricky: use this as stop bit length
772 1,
773 1,
774 1,
775 RC6_ADDRESS_OFFSET,
776 RC6_ADDRESS_OFFSET + RC6_ADDRESS_LEN,
777 RC6_COMMAND_OFFSET,
778 RC6_COMMAND_OFFSET + RC6_COMMAND_LEN,
779 RC6_COMPLETE_DATA_LEN_SHORT,
780 RC6_STOP_BIT,
781 RC6_LSB
782 };
783
784 #endif
785
786 #if IRMP_SUPPORT_RECS80EXT_PROTOCOL == 1
787
788 static PROGMEM IRMP_PARAMETER recs80ext_param =
789 {
790 IRMP_RECS80EXT_PROTOCOL,
791 RECS80EXT_PULSE_LEN_MIN,
792 RECS80EXT_PULSE_LEN_MAX,
793 RECS80EXT_1_PAUSE_LEN_MIN,
794 RECS80EXT_1_PAUSE_LEN_MAX,
795 RECS80EXT_PULSE_LEN_MIN,
796 RECS80EXT_PULSE_LEN_MAX,
797 RECS80EXT_0_PAUSE_LEN_MIN,
798 RECS80EXT_0_PAUSE_LEN_MAX,
799 RECS80EXT_ADDRESS_OFFSET,
800 RECS80EXT_ADDRESS_OFFSET + RECS80EXT_ADDRESS_LEN,
801 RECS80EXT_COMMAND_OFFSET,
802 RECS80EXT_COMMAND_OFFSET + RECS80EXT_COMMAND_LEN,
803 RECS80EXT_COMPLETE_DATA_LEN,
804 RECS80EXT_STOP_BIT,
805 RECS80EXT_LSB
806 };
807
808 #endif
809
810 #if IRMP_SUPPORT_RECS80EXT_PROTOCOL == 1
811
812 static PROGMEM IRMP_PARAMETER nubert_param =
813 {
814 IRMP_NUBERT_PROTOCOL,
815 NUBERT_1_PULSE_LEN_MIN,
816 NUBERT_1_PULSE_LEN_MAX,
817 NUBERT_1_PAUSE_LEN_MIN,
818 NUBERT_1_PAUSE_LEN_MAX,
819 NUBERT_0_PULSE_LEN_MIN,
820 NUBERT_0_PULSE_LEN_MAX,
821 NUBERT_0_PAUSE_LEN_MIN,
822 NUBERT_0_PAUSE_LEN_MAX,
823 NUBERT_ADDRESS_OFFSET,
824 NUBERT_ADDRESS_OFFSET + NUBERT_ADDRESS_LEN,
825 NUBERT_COMMAND_OFFSET,
826 NUBERT_COMMAND_OFFSET + NUBERT_COMMAND_LEN,
827 NUBERT_COMPLETE_DATA_LEN,
828 NUBERT_STOP_BIT,
829 NUBERT_LSB
830 };
831
832 #endif
833
834 static uint8_t irmp_bit; // current bit position
835 static IRMP_PARAMETER irmp_param;
836
837 static volatile uint8_t irmp_ir_detected;
838 static volatile uint8_t irmp_protocol;
839 static volatile uint16_t irmp_address;
840 static volatile uint16_t irmp_command;
841 static volatile uint16_t irmp_id; // only used for SAMSUNG protocol
842 static volatile uint8_t irmp_flags;
843
844 #ifdef DEBUG
845 static uint8_t IRMP_PIN;
846 #endif
847
848 /*---------------------------------------------------------------------------------------------------------------------------------------------------
849 * Initialize IRMP decoder
850 * @details Configures IRMP input pin
851 *---------------------------------------------------------------------------------------------------------------------------------------------------
852 */
853 #ifndef DEBUG
854 void
855 irmp_init (void)
856 {
857 #ifndef PIC_CCS_COMPILER
858 IRMP_PORT &= ~(1<<IRMP_BIT); // deactivate pullup
859 IRMP_DDR &= ~(1<<IRMP_BIT); // set pin to input
860 #endif // PIC_CCS_COMPILER
861
862 #if IRMP_LOGGING == 1
863 irmp_uart_init ();
864 #endif
865 }
866 #endif
867 /*---------------------------------------------------------------------------------------------------------------------------------------------------
868 * Get IRMP data
869 * @details gets decoded IRMP data
870 * @param pointer in order to store IRMP data
871 * @return TRUE: successful, FALSE: failed
872 *---------------------------------------------------------------------------------------------------------------------------------------------------
873 */
874 uint8_t
875 irmp_get_data (IRMP_DATA * irmp_data_p)
876 {
877 uint8_t rtc = FALSE;
878
879 if (irmp_ir_detected)
880 {
881 switch (irmp_protocol)
882 {
883 #if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1
884 case IRMP_SAMSUNG_PROTOCOL:
885 if ((irmp_command >> 8) == (~irmp_command & 0x00FF))
886 {
887 irmp_command &= 0xff;
888 irmp_command |= irmp_id << 8;
889 rtc = TRUE;
890 }
891 break;
892 #endif
893 #if IRMP_SUPPORT_NEC_PROTOCOL == 1
894 case IRMP_NEC_PROTOCOL:
895 if ((irmp_command >> 8) == (~irmp_command & 0x00FF))
896 {
897 irmp_command &= 0xff;
898 rtc = TRUE;
899 }
900 else if ((irmp_command & 0xFF00) == 0xD100)
901 {
902 DEBUG_PRINTF ("Switching to APPLE protocol\n");
903 irmp_protocol = IRMP_APPLE_PROTOCOL;
904 irmp_command &= 0xff;
905 rtc = TRUE;
906 }
907 break;
908 #endif
909 default:
910 rtc = TRUE;
911 }
912
913 if (rtc)
914 {
915 irmp_data_p->protocol = irmp_protocol;
916 irmp_data_p->address = irmp_address;
917 irmp_data_p->command = irmp_command;
918 irmp_data_p->flags = irmp_flags;
919 irmp_command = 0;
920 irmp_address = 0;
921 irmp_flags = 0;
922 }
923
924 irmp_ir_detected = FALSE;
925 }
926
927 return rtc;
928 }
929
930 // these statics must not be volatile, because they are only used by irmp_store_bit(), which is called by irmp_ISR()
931 static uint16_t irmp_tmp_address; // ir address
932 static uint16_t irmp_tmp_command; // ir command
933 #if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1
934 static uint16_t irmp_tmp_id; // ir id (only SAMSUNG)
935 #endif
936
937 static uint8_t irmp_bit; // current bit position
938
939 /*---------------------------------------------------------------------------------------------------------------------------------------------------
940 * store bit
941 * @details store bit in temp address or temp command
942 * @param value to store: 0 or 1
943 *---------------------------------------------------------------------------------------------------------------------------------------------------
944 */
945 static void
946 irmp_store_bit (uint8_t value)
947 {
948 if (irmp_bit >= irmp_param.address_offset && irmp_bit < irmp_param.address_end)
949 {
950 if (irmp_param.lsb_first)
951 {
952 irmp_tmp_address |= (((uint16_t) (value)) << (irmp_bit - irmp_param.address_offset)); // CV wants cast
953 }
954 else
955 {
956 irmp_tmp_address <<= 1;
957 irmp_tmp_address |= value;
958 }
959 }
960 else if (irmp_bit >= irmp_param.command_offset && irmp_bit < irmp_param.command_end)
961 {
962 if (irmp_param.lsb_first)
963 {
964 irmp_tmp_command |= (((uint16_t) (value)) << (irmp_bit - irmp_param.command_offset)); // CV wants cast
965 }
966 else
967 {
968 irmp_tmp_command <<= 1;
969 irmp_tmp_command |= value;
970 }
971 }
972 #if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1
973 else if (irmp_param.protocol == IRMP_SAMSUNG_PROTOCOL && irmp_bit >= SAMSUNG_ID_OFFSET && irmp_bit < SAMSUNG_ID_OFFSET + SAMSUNG_ID_LEN)
974 {
975 irmp_tmp_id |= (((uint16_t) (value)) << (irmp_bit - SAMSUNG_ID_OFFSET)); // store with LSB first
976 }
977 #endif
978 irmp_bit++;
979 }
980
981 /*---------------------------------------------------------------------------------------------------------------------------------------------------
982 * ISR routine
983 * @details ISR routine, called 10000 times per second
984 *---------------------------------------------------------------------------------------------------------------------------------------------------
985 */
986 void
987 irmp_ISR (void)
988 {
989 static uint8_t irmp_start_bit_detected; // flag: start bit detected
990 static uint8_t wait_for_space; // flag: wait for data bit space
991 static uint8_t wait_for_start_space; // flag: wait for start bit space
992 static uint8_t irmp_pulse_time; // count bit time for pulse
993 static uint8_t irmp_pause_time; // count bit time for pause
994 static uint16_t last_irmp_address; // save last irmp address to recognize key repetition
995 static uint16_t last_irmp_command; // save last irmp command to recognize key repetition
996 static uint16_t repetition_counter; // SIRCS repeats frame 2-5 times with 45 ms pause
997 #if IRMP_SUPPORT_DENON_PROTOCOL == 1
998 static uint16_t last_irmp_denon_command; // save last irmp command to recognize DENON frame repetition
999 #endif
1000 #if IRMP_SUPPORT_RC5_PROTOCOL == 1
1001 static uint8_t rc5_cmd_bit6; // bit 6 of RC5 command is the inverted 2nd start bit
1002 #endif
1003 #if IRMP_SUPPORT_RC5_PROTOCOL == 1 || IRMP_SUPPORT_RC6_PROTOCOL == 1
1004 static uint8_t rc5_last_pause; // last pause value
1005 static uint8_t rc5_last_value; // last bit value
1006 #endif
1007 uint8_t irmp_input; // input value
1008
1009 irmp_input = input(IRMP_PIN);
1010
1011 irmp_logIsr(irmp_input); // log ir signal, if IRMP_LOGGING defined
1012
1013 if (! irmp_ir_detected) // ir code already detected?
1014 { // no...
1015 if (! irmp_start_bit_detected) // start bit detected?
1016 { // no...
1017 if (!irmp_input) // receiving burst?
1018 { // yes...
1019 irmp_pulse_time++; // increment counter
1020 }
1021 else
1022 { // no...
1023 if (irmp_pulse_time) // it's dark....
1024 { // set flags for counting the time of darkness...
1025 irmp_start_bit_detected = 1;
1026 wait_for_start_space = 1;
1027 wait_for_space = 0;
1028 irmp_tmp_command = 0;
1029 irmp_tmp_address = 0;
1030 irmp_bit = 0xff;
1031 irmp_pause_time = 1; // 1st pause: set to 1, not to 0!
1032 #if IRMP_SUPPORT_RC5_PROTOCOL == 1
1033 rc5_cmd_bit6 = 0; // fm 2010-03-07: bugfix: reset it after incomplete RC5 frame!
1034 #endif
1035 }
1036 else
1037 {
1038 repetition_counter++;
1039 }
1040 }
1041 }
1042 else
1043 {
1044 if (wait_for_start_space) // we have received start bit...
1045 { // ...and are counting the time of darkness
1046 if (irmp_input) // still dark?
1047 { // yes
1048 irmp_pause_time++; // increment counter
1049
1050 if (irmp_pause_time > IRMP_TIMEOUT) // timeout?
1051 { // yes...
1052 DEBUG_PRINTF ("error 1: pause after start bit %d too long: %d\n", irmp_pulse_time, irmp_pause_time);
1053 irmp_start_bit_detected = 0; // reset flags, let's wait for another start bit
1054 irmp_pulse_time = 0;
1055 irmp_pause_time = 0;
1056 }
1057 }
1058 else
1059 { // receiving first data pulse!
1060 DEBUG_PRINTF ("start-bit: pulse = %d, pause = %d\n", irmp_pulse_time, irmp_pause_time);
1061
1062 #if IRMP_SUPPORT_SIRCS_PROTOCOL == 1
1063 if (irmp_pulse_time >= SIRCS_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= SIRCS_START_BIT_PULSE_LEN_MAX &&
1064 irmp_pause_time >= SIRCS_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= SIRCS_START_BIT_PAUSE_LEN_MAX)
1065 { // it's SIRCS
1066 DEBUG_PRINTF ("protocol = SIRCS, start bit timings: pulse: %2d - %2d, pause: %2d - %2d\n",
1067 SIRCS_START_BIT_PULSE_LEN_MIN, SIRCS_START_BIT_PULSE_LEN_MAX,
1068 SIRCS_START_BIT_PAUSE_LEN_MIN, SIRCS_START_BIT_PAUSE_LEN_MAX);
1069 memcpy_P (&irmp_param, &sircs_param, sizeof (IRMP_PARAMETER));
1070 }
1071 else
1072 #endif // IRMP_SUPPORT_SIRCS_PROTOCOL == 1
1073
1074 #if IRMP_SUPPORT_NEC_PROTOCOL == 1
1075 if (irmp_pulse_time >= NEC_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= NEC_START_BIT_PULSE_LEN_MAX &&
1076 ((irmp_pause_time >= NEC_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= NEC_START_BIT_PAUSE_LEN_MAX) ||
1077 (irmp_pause_time >= NEC_REPEAT_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= NEC_REPEAT_START_BIT_PAUSE_LEN_MAX)))
1078 { // it's NEC
1079 if (irmp_pause_time <= NEC_REPEAT_START_BIT_PAUSE_LEN_MAX)
1080 {
1081 DEBUG_PRINTF ("protocol = NEC (repetition frame), start bit timings: pulse: %2d - %2d, pause: %2d - %2d\n",
1082 NEC_START_BIT_PULSE_LEN_MIN, NEC_START_BIT_PULSE_LEN_MAX,
1083 NEC_REPEAT_START_BIT_PAUSE_LEN_MIN, NEC_REPEAT_START_BIT_PAUSE_LEN_MAX);
1084 }
1085 else
1086 {
1087 DEBUG_PRINTF ("protocol = NEC, start bit timings: pulse: %2d - %2d, pause: %2d - %2d\n",
1088 NEC_START_BIT_PULSE_LEN_MIN, NEC_START_BIT_PULSE_LEN_MAX,
1089 NEC_START_BIT_PAUSE_LEN_MIN, NEC_START_BIT_PAUSE_LEN_MAX);
1090 }
1091
1092 memcpy_P (&irmp_param, &nec_param, sizeof (IRMP_PARAMETER));
1093
1094 if (irmp_pause_time <= NEC_REPEAT_START_BIT_PAUSE_LEN_MAX)
1095 {
1096 irmp_param.address_offset = 0;
1097 irmp_param.address_end = 0;
1098 irmp_param.command_offset = 0;
1099 irmp_param.command_end = 0;
1100 irmp_param.complete_len = 0;
1101 }
1102 }
1103 else
1104 #endif // IRMP_SUPPORT_NEC_PROTOCOL == 1
1105
1106 #if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1
1107 if (irmp_pulse_time >= SAMSUNG_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= SAMSUNG_START_BIT_PULSE_LEN_MAX &&
1108 irmp_pause_time >= SAMSUNG_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= SAMSUNG_START_BIT_PAUSE_LEN_MAX)
1109 { // it's SAMSUNG
1110 DEBUG_PRINTF ("protocol = SAMSUNG, start bit timings: pulse: %2d - %2d, pause: %2d - %2d\n",
1111 SAMSUNG_START_BIT_PULSE_LEN_MIN, SAMSUNG_START_BIT_PULSE_LEN_MAX,
1112 SAMSUNG_START_BIT_PAUSE_LEN_MIN, SAMSUNG_START_BIT_PAUSE_LEN_MAX);
1113 memcpy_P (&irmp_param, &samsung_param, sizeof (IRMP_PARAMETER));
1114 }
1115 else
1116 #endif // IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1
1117
1118 #if IRMP_SUPPORT_MATSUSHITA_PROTOCOL == 1
1119 if (irmp_pulse_time >= MATSUSHITA_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= MATSUSHITA_START_BIT_PULSE_LEN_MAX &&
1120 irmp_pause_time >= MATSUSHITA_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= MATSUSHITA_START_BIT_PAUSE_LEN_MAX)
1121 { // it's MATSUSHITA
1122 DEBUG_PRINTF ("protocol = MATSUSHITA, start bit timings: pulse: %2d - %2d, pause: %2d - %2d\n",
1123 MATSUSHITA_START_BIT_PULSE_LEN_MIN, MATSUSHITA_START_BIT_PULSE_LEN_MAX,
1124 MATSUSHITA_START_BIT_PAUSE_LEN_MIN, MATSUSHITA_START_BIT_PAUSE_LEN_MAX);
1125 memcpy_P (&irmp_param, &matsushita_param, sizeof (IRMP_PARAMETER));
1126 }
1127 else
1128 #endif // IRMP_SUPPORT_MATSUSHITA_PROTOCOL == 1
1129
1130 #if IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1
1131 if (irmp_pulse_time >= KASEIKYO_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= KASEIKYO_START_BIT_PULSE_LEN_MAX &&
1132 irmp_pause_time >= KASEIKYO_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= KASEIKYO_START_BIT_PAUSE_LEN_MAX)
1133 { // it's KASEIKYO
1134 DEBUG_PRINTF ("protocol = KASEIKYO, start bit timings: pulse: %2d - %2d, pause: %2d - %2d\n",
1135 KASEIKYO_START_BIT_PULSE_LEN_MIN, KASEIKYO_START_BIT_PULSE_LEN_MAX,
1136 KASEIKYO_START_BIT_PAUSE_LEN_MIN, KASEIKYO_START_BIT_PAUSE_LEN_MAX);
1137 memcpy_P (&irmp_param, &kaseikyo_param, sizeof (IRMP_PARAMETER));
1138 }
1139 else
1140 #endif // IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1
1141
1142 #if IRMP_SUPPORT_RECS80_PROTOCOL == 1
1143 if (irmp_pulse_time >= RECS80_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= RECS80_START_BIT_PULSE_LEN_MAX &&
1144 irmp_pause_time >= RECS80_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= RECS80_START_BIT_PAUSE_LEN_MAX)
1145 { // it's RECS80
1146 DEBUG_PRINTF ("protocol = RECS80, start bit timings: pulse: %2d - %2d, pause: %2d - %2d\n",
1147 RECS80_START_BIT_PULSE_LEN_MIN, RECS80_START_BIT_PULSE_LEN_MAX,
1148 RECS80_START_BIT_PAUSE_LEN_MIN, RECS80_START_BIT_PAUSE_LEN_MAX);
1149 memcpy_P (&irmp_param, &recs80_param, sizeof (IRMP_PARAMETER));
1150 }
1151 else
1152 #endif // IRMP_SUPPORT_RECS80_PROTOCOL == 1
1153
1154 #if IRMP_SUPPORT_RC5_PROTOCOL == 1
1155 if (((irmp_pulse_time >= RC5_START_BIT_LEN_MIN && irmp_pulse_time <= RC5_START_BIT_LEN_MAX) ||
1156 (irmp_pulse_time >= 2 * RC5_START_BIT_LEN_MIN && irmp_pulse_time <= 2 * RC5_START_BIT_LEN_MAX)) &&
1157 ((irmp_pause_time >= RC5_START_BIT_LEN_MIN && irmp_pause_time <= RC5_START_BIT_LEN_MAX) ||
1158 (irmp_pause_time >= 2 * RC5_START_BIT_LEN_MIN && irmp_pause_time <= 2 * RC5_START_BIT_LEN_MAX)))
1159 { // it's RC5
1160 DEBUG_PRINTF ("protocol = RC5, start bit timings: pulse: %2d - %2d, pause: %2d - %2d\n",
1161 RC5_START_BIT_LEN_MIN, RC5_START_BIT_LEN_MAX,
1162 RC5_START_BIT_LEN_MIN, RC5_START_BIT_LEN_MAX);
1163 memcpy_P (&irmp_param, &rc5_param, sizeof (IRMP_PARAMETER));
1164 rc5_last_pause = irmp_pause_time;
1165
1166 if ((irmp_pulse_time > RC5_START_BIT_LEN_MAX && irmp_pulse_time <= 2 * RC5_START_BIT_LEN_MAX) ||
1167 (irmp_pause_time > RC5_START_BIT_LEN_MAX && irmp_pause_time <= 2 * RC5_START_BIT_LEN_MAX))
1168 {
1169 rc5_last_value = 0;
1170 rc5_cmd_bit6 = 1<<6;
1171 }
1172 else
1173 {
1174 rc5_last_value = 1;
1175 }
1176 }
1177 else
1178 #endif // IRMP_SUPPORT_RC5_PROTOCOL == 1
1179
1180 #if IRMP_SUPPORT_DENON_PROTOCOL == 1
1181 if ( (irmp_pulse_time >= DENON_PULSE_LEN_MIN && irmp_pulse_time <= DENON_PULSE_LEN_MAX) &&
1182 ((irmp_pause_time >= DENON_1_PAUSE_LEN_MIN && irmp_pause_time <= DENON_1_PAUSE_LEN_MAX) ||
1183 (irmp_pause_time >= DENON_0_PAUSE_LEN_MIN && irmp_pause_time <= DENON_0_PAUSE_LEN_MAX)))
1184 { // it's DENON
1185 DEBUG_PRINTF ("protocol = DENON, start bit timings: pulse: %2d - %2d, pause: %2d - %2d or %2d - %2d\n",
1186 DENON_PULSE_LEN_MIN, DENON_PULSE_LEN_MAX,
1187 DENON_1_PAUSE_LEN_MIN, DENON_1_PAUSE_LEN_MAX,
1188 DENON_0_PAUSE_LEN_MIN, DENON_0_PAUSE_LEN_MAX);
1189 memcpy_P (&irmp_param, &denon_param, sizeof (IRMP_PARAMETER));
1190 }
1191 else
1192 #endif // IRMP_SUPPORT_DENON_PROTOCOL == 1
1193
1194 #if IRMP_SUPPORT_RC6_PROTOCOL == 1
1195 if (irmp_pulse_time >= RC6_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= RC6_START_BIT_PULSE_LEN_MAX &&
1196 irmp_pause_time >= RC6_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= RC6_START_BIT_PAUSE_LEN_MAX)
1197 { // it's RC6
1198 DEBUG_PRINTF ("protocol = RC6, start bit timings: pulse: %2d - %2d, pause: %2d - %2d\n",
1199 RC6_START_BIT_PULSE_LEN_MIN, RC6_START_BIT_PULSE_LEN_MAX,
1200 RC6_START_BIT_PAUSE_LEN_MIN, RC6_START_BIT_PAUSE_LEN_MAX);
1201 memcpy_P (&irmp_param, &rc6_param, sizeof (IRMP_PARAMETER));
1202 rc5_last_pause = 0;
1203 rc5_last_value = 0;
1204 }
1205 else
1206 #endif // IRMP_SUPPORT_RC6_PROTOCOL == 1
1207
1208 #if IRMP_SUPPORT_RECS80EXT_PROTOCOL == 1
1209 if (irmp_pulse_time >= RECS80EXT_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= RECS80EXT_START_BIT_PULSE_LEN_MAX &&
1210 irmp_pause_time >= RECS80EXT_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= RECS80EXT_START_BIT_PAUSE_LEN_MAX)
1211 { // it's RECS80EXT
1212 DEBUG_PRINTF ("protocol = RECS80EXT, start bit timings: pulse: %2d - %2d, pause: %2d - %2d\n",
1213 RECS80EXT_START_BIT_PULSE_LEN_MIN, RECS80EXT_START_BIT_PULSE_LEN_MAX,
1214 RECS80EXT_START_BIT_PAUSE_LEN_MIN, RECS80EXT_START_BIT_PAUSE_LEN_MAX);
1215 memcpy_P (&irmp_param, &recs80ext_param, sizeof (IRMP_PARAMETER));
1216 }
1217 else
1218 #endif // IRMP_SUPPORT_RECS80EXT_PROTOCOL == 1
1219
1220 #if IRMP_SUPPORT_NUBERT_PROTOCOL == 1
1221 if (irmp_pulse_time >= NUBERT_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= NUBERT_START_BIT_PULSE_LEN_MAX &&
1222 irmp_pause_time >= NUBERT_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= NUBERT_START_BIT_PAUSE_LEN_MAX)
1223 { // it's NUBERT
1224 DEBUG_PRINTF ("protocol = NUBERT, start bit timings: pulse: %2d - %2d, pause: %2d - %2d\n",
1225 NUBERT_START_BIT_PULSE_LEN_MIN, NUBERT_START_BIT_PULSE_LEN_MAX,
1226 NUBERT_START_BIT_PAUSE_LEN_MIN, NUBERT_START_BIT_PAUSE_LEN_MAX);
1227 memcpy_P (&irmp_param, &nubert_param, sizeof (IRMP_PARAMETER));
1228 }
1229 else
1230 #endif // IRMP_SUPPORT_NUBERT_PROTOCOL == 1
1231
1232 {
1233 DEBUG_PRINTF ("protocol = UNKNOWN\n");
1234 irmp_start_bit_detected = 0; // wait for another start bit...
1235 }
1236
1237 if (irmp_start_bit_detected)
1238 {
1239 DEBUG_PRINTF ("pulse_1 = %2d - %2d\n", irmp_param.pulse_1_len_min, irmp_param.pulse_1_len_max);
1240 DEBUG_PRINTF ("pause_1 = %2d - %2d\n", irmp_param.pause_1_len_min, irmp_param.pause_1_len_max);
1241 if (irmp_param.protocol == IRMP_RC6_PROTOCOL)
1242 {
1243 DEBUG_PRINTF ("pulse_toggle = %2d - %2d\n", RC6_TOGGLE_BIT_LEN_MIN, RC6_TOGGLE_BIT_LEN_MAX);
1244 }
1245 DEBUG_PRINTF ("pulse_0 = %2d - %2d\n", irmp_param.pulse_0_len_min, irmp_param.pulse_0_len_max);
1246 DEBUG_PRINTF ("pause_0 = %2d - %2d\n", irmp_param.pause_0_len_min, irmp_param.pause_0_len_max);
1247 DEBUG_PRINTF ("command_offset = %d\n", irmp_param.command_offset);
1248 DEBUG_PRINTF ("command_len = %d\n", irmp_param.command_end - irmp_param.command_offset);
1249 DEBUG_PRINTF ("complete_len = %d\n", irmp_param.complete_len);
1250 DEBUG_PRINTF ("stop_bit = %d\n", irmp_param.stop_bit);
1251 }
1252
1253 irmp_bit = 0;
1254
1255 #if IRMP_SUPPORT_RC5_PROTOCOL == 1
1256 if (irmp_param.protocol == IRMP_RC5_PROTOCOL)
1257 {
1258 if (irmp_pause_time > RC5_START_BIT_LEN_MAX && irmp_pause_time <= 2 * RC5_START_BIT_LEN_MAX)
1259 {
1260 DEBUG_PRINTF ("[bit %2d: pulse = %2d, pause = %2d] ", irmp_bit, irmp_pulse_time, irmp_pause_time);
1261 DEBUG_PUTCHAR ('1');
1262 DEBUG_PUTCHAR ('\n');
1263 irmp_store_bit (1);
1264 }
1265 else if (! rc5_last_value)
1266 {
1267 DEBUG_PRINTF ("[bit %2d: pulse = %2d, pause = %2d] ", irmp_bit, irmp_pulse_time, irmp_pause_time);
1268 DEBUG_PUTCHAR ('0');
1269 DEBUG_PUTCHAR ('\n');
1270 irmp_store_bit (0);
1271 }
1272 }
1273 else
1274 #endif // IRMP_SUPPORT_RC5_PROTOCOL == 1
1275
1276 #if IRMP_SUPPORT_DENON_PROTOCOL == 1
1277 if (irmp_param.protocol == IRMP_DENON_PROTOCOL)
1278 {
1279 DEBUG_PRINTF ("[bit %2d: pulse = %2d, pause = %2d] ", irmp_bit, irmp_pulse_time, irmp_pause_time);
1280
1281 if (irmp_pause_time >= DENON_1_PAUSE_LEN_MIN && irmp_pause_time <= DENON_1_PAUSE_LEN_MAX)
1282 { // pause timings correct for "1"?
1283 DEBUG_PUTCHAR ('1'); // yes, store 1
1284 DEBUG_PUTCHAR ('\n');
1285 irmp_store_bit (1);
1286 }
1287 else // if (irmp_pause_time >= DENON_0_PAUSE_LEN_MIN && irmp_pause_time <= DENON_0_PAUSE_LEN_MAX)
1288 { // pause timings correct for "0"?
1289 DEBUG_PUTCHAR ('0'); // yes, store 0
1290 DEBUG_PUTCHAR ('\n');
1291 irmp_store_bit (0);
1292 }
1293 }
1294 #endif // IRMP_SUPPORT_DENON_PROTOCOL == 1
1295
1296 irmp_pulse_time = 1; // set counter to 1, not 0
1297 irmp_pause_time = 0;
1298 wait_for_start_space = 0;
1299 }
1300 }
1301 else if (wait_for_space) // the data section....
1302 { // counting the time of darkness....
1303 uint8_t got_light = FALSE;
1304
1305 if (irmp_input) // still dark?
1306 { // yes...
1307 if (irmp_bit == irmp_param.complete_len && irmp_param.stop_bit == 1)
1308 {
1309 if (irmp_pulse_time >= irmp_param.pulse_0_len_min && irmp_pulse_time <= irmp_param.pulse_0_len_max)
1310 {
1311 #ifdef DEBUG
1312 if (irmp_param.protocol != IRMP_RC5_PROTOCOL)
1313 {
1314 DEBUG_PRINTF ("stop bit detected\n");
1315 }
1316 #endif
1317 irmp_param.stop_bit = 0;
1318 }
1319 else
1320 {
1321 DEBUG_PRINTF ("stop bit timing wrong\n");
1322
1323 irmp_start_bit_detected = 0; // wait for another start bit...
1324 irmp_pulse_time = 0;
1325 irmp_pause_time = 0;
1326 }
1327 }
1328 else
1329 {
1330 irmp_pause_time++; // increment counter
1331
1332 #if IRMP_SUPPORT_SIRCS_PROTOCOL == 1
1333 if (irmp_param.protocol == IRMP_SIRCS_PROTOCOL && // Sony has a variable number of bits:
1334 irmp_pause_time > SIRCS_PAUSE_LEN_MAX && // minimum is 12
1335 irmp_bit >= 12 - 1) // pause too long?
1336 { // yes, break and close this frame
1337 irmp_param.complete_len = irmp_bit + 1; // set new complete length
1338 got_light = TRUE; // this is a lie, but helps (generates stop bit)
1339 irmp_param.command_end = irmp_param.command_offset + irmp_bit + 1; // correct command length
1340 irmp_pause_time = SIRCS_PAUSE_LEN_MAX - 1; // correct pause length
1341 }
1342 else
1343 #endif
1344 #if IRMP_SUPPORT_RC5_PROTOCOL == 1
1345 if (irmp_param.protocol == IRMP_RC5_PROTOCOL &&
1346 irmp_pause_time > 2 * RC5_BIT_LEN_MAX && irmp_bit >= RC5_COMPLETE_DATA_LEN - 2 && !irmp_param.stop_bit)
1347 { // special rc5 decoder
1348 got_light = TRUE; // this is a lie, but generates a stop bit ;-)
1349 irmp_param.stop_bit = TRUE; // set flag
1350 }
1351 else
1352 #endif
1353 #if IRMP_SUPPORT_RC6_PROTOCOL == 1
1354 if (irmp_param.protocol == IRMP_RC6_PROTOCOL &&
1355 irmp_pause_time > 2 * RC6_BIT_LEN_MAX && irmp_bit >= irmp_param.complete_len - 2 && !irmp_param.stop_bit)
1356 { // special rc6 decoder
1357 got_light = TRUE; // this is a lie, but generates a stop bit ;-)
1358 irmp_param.stop_bit = TRUE; // set flag
1359 }
1360 else
1361 #endif
1362 if (irmp_pause_time > IRMP_TIMEOUT) // timeout?
1363 { // yes...
1364 if (irmp_bit == irmp_param.complete_len - 1 && irmp_param.stop_bit == 0)
1365 {
1366 irmp_bit++;
1367 }
1368 else
1369 {
1370 DEBUG_PRINTF ("error 2: pause %d after data bit %d too long\n", irmp_pause_time, irmp_bit);
1371
1372 irmp_start_bit_detected = 0; // wait for another start bit...
1373 irmp_pulse_time = 0;
1374 irmp_pause_time = 0;
1375 }
1376 }
1377 }
1378 }
1379 else
1380 { // got light now!
1381 got_light = TRUE;
1382 }
1383
1384 if (got_light)
1385 {
1386 DEBUG_PRINTF ("[bit %2d: pulse = %2d, pause = %2d] ", irmp_bit, irmp_pulse_time, irmp_pause_time);
1387
1388 #if IRMP_SUPPORT_RC5_PROTOCOL == 1
1389 if (irmp_param.protocol == IRMP_RC5_PROTOCOL) // special rc5 decoder
1390 {
1391 if (irmp_pulse_time > RC5_BIT_LEN_MAX && irmp_pulse_time <= 2 * RC5_BIT_LEN_MAX)
1392 {
1393 DEBUG_PUTCHAR ('1');
1394 irmp_store_bit (1);
1395 DEBUG_PUTCHAR ('0');
1396 DEBUG_PUTCHAR ('\n');
1397 irmp_store_bit (0);
1398 rc5_last_value = 0;
1399 }
1400
1401 else // if (irmp_pulse_time >= RC5_BIT_LEN_MIN && irmp_pulse_time <= RC5_BIT_LEN_MAX)
1402 {
1403 uint8_t rc5_value;
1404
1405 if (rc5_last_pause > RC5_BIT_LEN_MAX && rc5_last_pause <= 2 * RC5_BIT_LEN_MAX)
1406 {
1407 rc5_value = rc5_last_value ? 0 : 1;
1408 rc5_last_value = rc5_value;
1409 }
1410 else
1411 {
1412 rc5_value = rc5_last_value;
1413 }
1414
1415 DEBUG_PUTCHAR (rc5_value + '0');
1416 DEBUG_PUTCHAR ('\n');
1417 irmp_store_bit (rc5_value);
1418 }
1419
1420 rc5_last_pause = irmp_pause_time;
1421 wait_for_space = 0;
1422 }
1423 else
1424 #endif
1425
1426 #if IRMP_SUPPORT_RC6_PROTOCOL == 1
1427 if (irmp_param.protocol == IRMP_RC6_PROTOCOL) // special rc6 decoder
1428 {
1429 switch (irmp_bit)
1430 { // handle toggle bit, which is 2 times longer than other bits
1431 case 3:
1432 case 4:
1433 case 5:
1434 if (irmp_pulse_time > RC6_TOGGLE_BIT_LEN_MAX && irmp_pause_time > RC6_TOGGLE_BIT_LEN_MAX)
1435 {
1436 DEBUG_PUTCHAR ('1');
1437 irmp_store_bit (1);
1438 }
1439
1440 DEBUG_PUTCHAR ('0');
1441 irmp_store_bit (0);
1442 rc5_last_value = 0;
1443 DEBUG_PUTCHAR ('\n');
1444 break;
1445
1446 default:
1447 if (irmp_pulse_time > RC6_BIT_LEN_MAX && irmp_pulse_time <= 2 * RC6_BIT_LEN_MAX)
1448 {
1449 DEBUG_PUTCHAR ('0');
1450 irmp_store_bit (0);
1451 DEBUG_PUTCHAR ('1');
1452 DEBUG_PUTCHAR ('\n');
1453 irmp_store_bit (1);
1454 rc5_last_value = 1;
1455 }
1456 else // if (irmp_pulse_time >= RC6_BIT_LEN_MIN && irmp_pulse_time <= RC6_BIT_LEN_MAX)
1457 {
1458 uint8_t rc5_value;
1459
1460 if (rc5_last_pause > RC6_BIT_LEN_MAX && rc5_last_pause <= 2 * RC6_BIT_LEN_MAX)
1461 {
1462 rc5_value = rc5_last_value ? 0 : 1;
1463 rc5_last_value = rc5_value;
1464 }
1465 else
1466 {
1467 rc5_value = rc5_last_value;
1468 }
1469
1470 if (irmp_bit == 1 && rc5_value == 0)
1471 {
1472 irmp_param.complete_len = RC6_COMPLETE_DATA_LEN_LONG;
1473 }
1474
1475 DEBUG_PUTCHAR (rc5_value + '0');
1476 DEBUG_PUTCHAR ('\n');
1477 irmp_store_bit (rc5_value);
1478 }
1479
1480 rc5_last_pause = irmp_pause_time;
1481 break;
1482 } // switch
1483
1484 wait_for_space = 0;
1485 }
1486 else
1487 #endif
1488
1489 #if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1
1490 if (irmp_param.protocol == IRMP_SAMSUNG_PROTOCOL && irmp_bit == 16) // Samsung: 16th bit
1491 {
1492 if (irmp_pulse_time >= SAMSUNG_PULSE_LEN_MIN && irmp_pulse_time <= SAMSUNG_PULSE_LEN_MAX &&
1493 irmp_pause_time >= SAMSUNG_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= SAMSUNG_START_BIT_PAUSE_LEN_MAX)
1494 {
1495 DEBUG_PRINTF ("SYNC\n");
1496 wait_for_space = 0;
1497 irmp_tmp_id = 0;
1498 irmp_bit++;
1499 }
1500 else if (irmp_pulse_time >= SAMSUNG_PULSE_LEN_MIN && irmp_pulse_time <= SAMSUNG_PULSE_LEN_MAX)
1501 {
1502 if (irmp_pause_time >= SAMSUNG_1_PAUSE_LEN_MIN && irmp_pause_time <= SAMSUNG_1_PAUSE_LEN_MAX)
1503 {
1504 DEBUG_PUTCHAR ('1');
1505 DEBUG_PUTCHAR ('\n');
1506 irmp_store_bit (1);
1507 wait_for_space = 0;
1508 }
1509 else
1510 {
1511 DEBUG_PUTCHAR ('0');
1512 DEBUG_PUTCHAR ('\n');
1513 irmp_store_bit (0);
1514 wait_for_space = 0;
1515 }
1516
1517 DEBUG_PRINTF ("Switching to SAMSUNG32 protocol\n");
1518
1519 irmp_param.protocol = IRMP_SAMSUNG32_PROTOCOL;
1520 irmp_param.command_offset = SAMSUNG32_COMMAND_OFFSET;
1521 irmp_param.command_end = SAMSUNG32_COMMAND_OFFSET + SAMSUNG32_COMMAND_LEN;
1522 irmp_param.complete_len = SAMSUNG32_COMPLETE_DATA_LEN;
1523 }
1524 else
1525 { // timing incorrect!
1526 DEBUG_PRINTF ("error 3: timing not correct: data bit %d, pulse: %d, pause: %d\n", irmp_bit, irmp_pulse_time, irmp_pause_time);
1527 irmp_start_bit_detected = 0; // reset flags and wait for next start bit
1528 irmp_pause_time = 0;
1529 }
1530
1531 irmp_pulse_time = 1; // set counter to 1, not 0
1532 }
1533 else
1534 #endif // IRMP_SUPPORT_SAMSUNG_PROTOCOL
1535
1536 if (irmp_pulse_time >= irmp_param.pulse_1_len_min && irmp_pulse_time <= irmp_param.pulse_1_len_max &&
1537 irmp_pause_time >= irmp_param.pause_1_len_min && irmp_pause_time <= irmp_param.pause_1_len_max)
1538 { // pulse & pause timings correct for "1"?
1539 DEBUG_PUTCHAR ('1');
1540 DEBUG_PUTCHAR ('\n');
1541 irmp_store_bit (1);
1542 wait_for_space = 0;
1543 }
1544 else if (irmp_pulse_time >= irmp_param.pulse_0_len_min && irmp_pulse_time <= irmp_param.pulse_0_len_max &&
1545 irmp_pause_time >= irmp_param.pause_0_len_min && irmp_pause_time <= irmp_param.pause_0_len_max)
1546 { // pulse & pause timings correct for "0"?
1547 DEBUG_PUTCHAR ('0');
1548 DEBUG_PUTCHAR ('\n');
1549 irmp_store_bit (0);
1550 wait_for_space = 0;
1551 }
1552 else
1553 { // timing incorrect!
1554 DEBUG_PRINTF ("error 3: timing not correct: data bit %d, pulse: %d, pause: %d\n", irmp_bit, irmp_pulse_time, irmp_pause_time);
1555 irmp_start_bit_detected = 0; // reset flags and wait for next start bit
1556 irmp_pause_time = 0;
1557 }
1558
1559 irmp_pulse_time = 1; // set counter to 1, not 0
1560 }
1561 }
1562 else
1563 { // counting the pulse length ...
1564 if (!irmp_input) // still light?
1565 { // yes...
1566 irmp_pulse_time++; // increment counter
1567 }
1568 else
1569 { // now it's dark!
1570 wait_for_space = 1; // let's count the time (see above)
1571 irmp_pause_time = 1; // set pause counter to 1, not 0
1572 }
1573 }
1574
1575 if (irmp_bit == irmp_param.complete_len && irmp_param.stop_bit == 0) // enough bits received?
1576 {
1577 // if SIRCS/SAMSUNG32 protocol and the code will be repeated within 50 ms, we will ignore it.
1578 if ((irmp_param.protocol == IRMP_SIRCS_PROTOCOL ||
1579 irmp_param.protocol == IRMP_SAMSUNG32_PROTOCOL ||
1580 irmp_param.protocol == IRMP_NUBERT_PROTOCOL) &&
1581 last_irmp_command == irmp_tmp_command && repetition_counter < AUTO_REPETITION_LEN)
1582 {
1583 DEBUG_PRINTF ("code skipped, recognized SIRCS, SAMSUNG32 or NUBERT repetition, counter = %d, auto repetition len = %d\n",
1584 repetition_counter, AUTO_REPETITION_LEN);
1585 repetition_counter = 0;
1586 }
1587 else
1588 {
1589 DEBUG_PRINTF ("code detected, length = %d\n", irmp_bit);
1590 irmp_ir_detected = TRUE;
1591
1592 #if IRMP_SUPPORT_DENON_PROTOCOL == 1
1593 if (irmp_param.protocol == IRMP_DENON_PROTOCOL)
1594 { // check for repetition frame
1595 if ((~irmp_tmp_command & 0x3FF) == last_irmp_denon_command) // command bits must be inverted
1596 {
1597 irmp_tmp_command = last_irmp_denon_command; // use command received before!
1598
1599 irmp_protocol = irmp_param.protocol; // store protocol
1600 irmp_address = irmp_tmp_address; // store address
1601 irmp_command = irmp_tmp_command ; // store command
1602 }
1603 else
1604 {
1605 DEBUG_PRINTF ("waiting for inverted command repetition\n");
1606 irmp_ir_detected = FALSE;
1607 last_irmp_denon_command = irmp_tmp_command;
1608 }
1609 }
1610 else
1611 #endif // IRMP_SUPPORT_DENON_PROTOCOL
1612 {
1613 #if IRMP_SUPPORT_NEC_PROTOCOL == 1
1614 if (irmp_param.protocol == IRMP_NEC_PROTOCOL && irmp_bit == 0) // repetition frame
1615 {
1616 irmp_tmp_address = last_irmp_address; // address is last address
1617 irmp_tmp_command = last_irmp_command; // command is last command
1618 irmp_flags |= IRMP_FLAG_REPETITION;
1619 }
1620 #endif // IRMP_SUPPORT_NEC_PROTOCOL
1621 irmp_protocol = irmp_param.protocol;
1622 irmp_address = irmp_tmp_address; // store address
1623 #if IRMP_SUPPORT_NEC_PROTOCOL == 1
1624 last_irmp_address = irmp_tmp_address; // store as last address, too
1625 #endif
1626
1627 #if IRMP_SUPPORT_RC5_PROTOCOL == 1
1628 irmp_tmp_command |= rc5_cmd_bit6; // store bit 6
1629 #endif
1630 irmp_command = irmp_tmp_command; // store command
1631
1632 #if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1
1633 irmp_id = irmp_tmp_id;
1634 #endif
1635 }
1636 }
1637
1638 if (irmp_ir_detected)
1639 {
1640 if (last_irmp_command == irmp_command &&
1641 last_irmp_address == irmp_address &&
1642 repetition_counter < IRMP_REPETITION_TIME)
1643 {
1644 irmp_flags |= IRMP_FLAG_REPETITION;
1645 }
1646
1647 last_irmp_address = irmp_tmp_address; // store as last address, too
1648 last_irmp_command = irmp_tmp_command; // store as last command, too
1649
1650 repetition_counter = 0;
1651 }
1652
1653 irmp_start_bit_detected = 0; // and wait for next start bit
1654 irmp_tmp_command = 0;
1655 irmp_pulse_time = 0;
1656 irmp_pause_time = 0;
1657 }
1658 }
1659 }
1660 }
1661
1662 #ifdef DEBUG
1663
1664 // main function - for unix/linux + windows only!
1665 // AVR: see main.c!
1666 // Compile it under linux with:
1667 // cc irmp.c -o irmp
1668 //
1669 // usage: ./irmp [-v|-s|-a] < file
1670
1671 int
1672 main (int argc, char ** argv)
1673 {
1674 int i;
1675 int verbose = FALSE;
1676 int analyze = FALSE;
1677 int ch;
1678 int last_ch = 0;
1679 int pulse = 0;
1680 int pause = 0;
1681
1682 int min_pulse_long = 100000;
1683 int max_pulse_long = 0;
1684 int sum_pulses_long = 0;
1685 int n_pulses_long = 0;
1686
1687 int min_pulse_short = 100000;
1688 int max_pulse_short = 0;
1689 int sum_pulses_short = 0;
1690 int n_pulses_short = 0;
1691
1692 int min_pause_long = 100000;
1693 int max_pause_long = 0;
1694 int sum_pauses_long = 0;
1695 int n_pauses_long = 0;
1696
1697 int min_pause_short = 100000;
1698 int max_pause_short = 0;
1699 int sum_pauses_short = 0;
1700 int n_pauses_short = 0;
1701
1702 int min_start_pulse = 100000;
1703 int max_start_pulse = 0;
1704 int sum_start_pulses = 0;
1705 int n_start_pulses = 0;
1706
1707 int min_start_pause = 100000;
1708 int max_start_pause = 0;
1709 int sum_start_pauses = 0;
1710 int n_start_pauses = 0;
1711
1712 int first_pulse = TRUE;
1713 int first_pause = TRUE;
1714
1715 IRMP_DATA irmp_data;
1716
1717 if (argc == 2)
1718 {
1719 if (! strcmp (argv[1], "-v"))
1720 {
1721 verbose = TRUE;
1722 }
1723 else if (! strcmp (argv[1], "-a"))
1724 {
1725 analyze = TRUE;
1726 verbose = TRUE;
1727 }
1728 else if (! strcmp (argv[1], "-s"))
1729 {
1730 silent = TRUE;
1731 }
1732 }
1733
1734 IRMP_PIN = 0xFF;
1735
1736 while ((ch = getchar ()) != EOF)
1737 {
1738 if (ch == '_' || ch == '0')
1739 {
1740 if (last_ch != ch)
1741 {
1742 if (verbose && pause > 0)
1743 {
1744 printf ("pause: %d\n", pause);
1745
1746 if (first_pause)
1747 {
1748 if (min_start_pause > pause)
1749 {
1750 min_start_pause = pause;
1751 }
1752 if (max_start_pause < pause)
1753 {
1754 max_start_pause = pause;
1755 }
1756 n_start_pauses++;
1757 sum_start_pauses += pause;
1758 first_pause = FALSE;
1759 }
1760 else
1761 {
1762 if (pause >= 10)
1763 {
1764 if (pause > 100) // perhaps repetition frame follows
1765 {
1766 first_pulse = TRUE;
1767 first_pause = TRUE;
1768 }
1769 else
1770 {
1771 if (min_pause_long > pause)
1772 {
1773 min_pause_long = pause;
1774 }
1775 if (max_pause_long < pause)
1776 {
1777 max_pause_long = pause;
1778 }
1779 n_pauses_long++;
1780 sum_pauses_long += pause;
1781 }
1782 }
1783 else
1784 {
1785 if (min_pause_short > pause)
1786 {
1787 min_pause_short = pause;
1788 }
1789 if (max_pause_short < pause)
1790 {
1791 max_pause_short = pause;
1792 }
1793 n_pauses_short++;
1794 sum_pauses_short += pause;
1795 }
1796 }
1797 }
1798 pause = 0;
1799 }
1800 pulse++;
1801 IRMP_PIN = 0x00;
1802 }
1803 else if (ch == 0xaf || ch == '-' || ch == '1')
1804 {
1805 if (last_ch != ch)
1806 {
1807 if (verbose)
1808 {
1809 printf ("pulse: %d ", pulse);
1810
1811 if (first_pulse)
1812 {
1813 if (min_start_pulse > pulse)
1814 {
1815 min_start_pulse = pulse;
1816 }
1817 if (max_start_pulse < pulse)
1818 {
1819 max_start_pulse = pulse;
1820 }
1821 n_start_pulses++;
1822 sum_start_pulses += pulse;
1823 first_pulse = FALSE;
1824 }
1825 else
1826 {
1827 if (pulse >= 10)
1828 {
1829 if (min_pulse_long > pulse)
1830 {
1831 min_pulse_long = pulse;
1832 }
1833 if (max_pulse_long < pulse)
1834 {
1835 max_pulse_long = pulse;
1836 }
1837 n_pulses_long++;
1838 sum_pulses_long += pulse;
1839 }
1840 else
1841 {
1842 if (min_pulse_short > pulse)
1843 {
1844 min_pulse_short = pulse;
1845 }
1846 if (max_pulse_short < pulse)
1847 {
1848 max_pulse_short = pulse;
1849 }
1850 n_pulses_short++;
1851 sum_pulses_short += pulse;
1852 }
1853 }
1854 }
1855 pulse = 0;
1856 }
1857 pause++;
1858 IRMP_PIN = 0xff;
1859 }
1860 else if (ch == '\n')
1861 {
1862 IRMP_PIN = 0xff;
1863
1864 if (verbose && pause > 0)
1865 {
1866 printf ("pause: %d\n", pause);
1867 }
1868 pause = 0;
1869
1870 if (! analyze)
1871 {
1872 for (i = 0; i < 8000; i++) // newline: long pause of 800 msec
1873 {
1874 irmp_ISR ();
1875 }
1876 }
1877 first_pulse = TRUE;
1878 first_pause = TRUE;
1879 }
1880 else if (ch == '#')
1881 {
1882 puts ("-------------------------------------------------------------------");
1883 putchar (ch);
1884
1885 while ((ch = getchar()) != '\n' && ch != EOF)
1886 {
1887 if (ch != '\r') // ignore CR in DOS/Windows files
1888 {
1889 putchar (ch);
1890 }
1891 }
1892 putchar ('\n');
1893 }
1894
1895 last_ch = ch;
1896
1897 if (! analyze)
1898 {
1899 irmp_ISR ();
1900 }
1901
1902 if (irmp_get_data (&irmp_data))
1903 {
1904 printf ("protcol = %d, address = 0x%04x, code = 0x%04x, flags = 0x%02x\n",
1905 irmp_data.protocol, irmp_data.address, irmp_data.command, irmp_data.flags);
1906 }
1907 }
1908
1909 if (analyze)
1910 {
1911 printf ("\nSTATITSTICS:\n");
1912 printf ("---------------------------------\n");
1913 printf ("number of start pulses: %d\n", n_start_pulses);
1914 printf ("minimum start pulse length: %d usec\n", (F_INTERRUPTS * min_start_pulse) / 100);
1915 printf ("maximum start pulse length: %d usec\n", (F_INTERRUPTS * max_start_pulse) / 100);
1916 if (n_start_pulses > 0)
1917 {
1918 printf ("average start pulse length: %d usec\n", ((F_INTERRUPTS * sum_start_pulses) / n_start_pulses) / 100);
1919 }
1920 putchar ('\n');
1921 printf ("number of start pauses: %d\n", n_start_pauses);
1922 if (n_start_pauses > 0)
1923 {
1924 printf ("minimum start pause length: %d usec\n", (F_INTERRUPTS * min_start_pause) / 100);
1925 printf ("maximum start pause length: %d usec\n", (F_INTERRUPTS * max_start_pause) / 100);
1926 printf ("average start pause length: %d usec\n", ((F_INTERRUPTS * sum_start_pauses) / n_start_pauses) / 100);
1927 }
1928 putchar ('\n');
1929 printf ("number of long pulses: %d\n", n_pulses_long);
1930 if (n_pulses_long > 0)
1931 {
1932 printf ("minimum long pulse length: %d usec\n", (F_INTERRUPTS * min_pulse_long) / 100);
1933 printf ("maximum long pulse length: %d usec\n", (F_INTERRUPTS * max_pulse_long) / 100);
1934 printf ("average long pulse length: %d usec\n", ((F_INTERRUPTS * sum_pulses_long) / n_pulses_long) / 100);
1935 }
1936 putchar ('\n');
1937 printf ("number of short pulses: %d\n", n_pulses_short);
1938 if (n_pulses_short > 0)
1939 {
1940 printf ("minimum short pulse length: %d usec\n", (F_INTERRUPTS * min_pulse_short) / 100);
1941 printf ("maximum short pulse length: %d usec\n", (F_INTERRUPTS * max_pulse_short) / 100);
1942 printf ("average short pulse length: %d usec\n", ((F_INTERRUPTS * sum_pulses_short) / n_pulses_short) / 100);
1943
1944 }
1945 putchar ('\n');
1946 printf ("number of long pauses: %d\n", n_pauses_long);
1947 if (n_pauses_long > 0)
1948 {
1949 printf ("minimum long pause length: %d usec\n", (F_INTERRUPTS * min_pause_long) / 100);
1950 printf ("maximum long pause length: %d usec\n", (F_INTERRUPTS * max_pause_long) / 100);
1951 printf ("average long pause length: %d usec\n", ((F_INTERRUPTS * sum_pauses_long) / n_pauses_long) / 100);
1952 }
1953 putchar ('\n');
1954 printf ("number of short pauses: %d\n", n_pauses_short);
1955 if (n_pauses_short > 0)
1956 {
1957 printf ("minimum short pause length: %d usec\n", (F_INTERRUPTS * min_pause_short) / 100);
1958 printf ("maximum short pause length: %d usec\n", (F_INTERRUPTS * max_pause_short) / 100);
1959 printf ("average short pause length: %d usec\n", ((F_INTERRUPTS * sum_pauses_short) / n_pauses_short) / 100);
1960 }
1961 }
1962 return 0;
1963 }
1964
1965 #endif // DEBUG