]> cloudbase.mooo.com Git - irmp.git/blob - irsnd.c
Version 1.1.1: converted newlines
[irmp.git] / irsnd.c
1 /*---------------------------------------------------------------------------------------------------------------------------------------------------
2 * @file irsnd.c
3 *
4 * Copyright (c) 2010 Frank Meyer - frank(at)fli4l.de
5 *
6 * $Id: irsnd.c,v 1.7 2010/04/14 13:21:39 fm Exp $
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *---------------------------------------------------------------------------------------------------------------------------------------------------
13 */
14
15 #ifdef unix // test/debug on linux/unix
16 #include <stdio.h>
17 #include <unistd.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <inttypes.h>
21
22 #define DEBUG
23 #define F_CPU 8000000L
24
25 #else // not unix:
26
27 #ifdef WIN32 // test/debug on windows
28 #include <stdio.h>
29 #define F_CPU 8000000L
30 typedef unsigned char uint8_t;
31 typedef unsigned short uint16_t;
32 #define DEBUG
33
34 #else
35
36 #ifdef CODEVISION
37 #define COM2A0 6
38 #define WGM21 1
39 #define CS20 0
40 #else
41 #include <inttypes.h>
42 #include <avr/io.h>
43 #include <util/delay.h>
44 #include <avr/pgmspace.h>
45 #endif // CODEVISION
46
47 #endif // WIN32
48 #endif // unix
49
50 #include "irmpconfig.h"
51 #include "irmp.h"
52 #include "irsnd.h"
53
54 /*---------------------------------------------------------------------------------------------------------------------------------------------------
55 * Change settings from 1 to 0 if you want to disable one or more encoders.
56 * This saves program space.
57 * 1 enable decoder
58 * 0 disable decoder
59 *---------------------------------------------------------------------------------------------------------------------------------------------------
60 */
61 #define IRSND_SUPPORT_SIRCS_PROTOCOL 1 // flag: support SIRCS uses ~150 bytes
62 #define IRSND_SUPPORT_NEC_PROTOCOL 1 // flag: support NEC uses ~100 bytes
63 #define IRSND_SUPPORT_SAMSUNG_PROTOCOL 1 // flag: support Samsung + Samsung32 uses ~300 bytes
64 #define IRSND_SUPPORT_MATSUSHITA_PROTOCOL 1 // flag: support Matsushita uses ~150 bytes
65 #define IRSND_SUPPORT_KASEIKYO_PROTOCOL 0 // flag: support Kaseikyo NOT SUPPORTED YET!
66 #define IRSND_SUPPORT_RECS80_PROTOCOL 1 // flag: support RECS80 uses ~100 bytes
67 #define IRSND_SUPPORT_RC5_PROTOCOL 1 // flag: support RC5 uses ~250 bytes
68 #define IRSND_SUPPORT_DENON_PROTOCOL 1 // flag: support DENON uses ~200 bytes
69 #define IRSND_SUPPORT_RC6_PROTOCOL 0 // flag: support RC6 NOT SUPPORTED YET!
70 #define IRSND_SUPPORT_RECS80EXT_PROTOCOL 1 // flag: support RECS80EXT uses ~100 bytes
71 #define IRSND_SUPPORT_NUBERT_PROTOCOL 1 // flag: support NUBERT uses ~100 bytes
72 #define IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL 1 // flag: support Bang&Olufsen uses ~250 bytes
73
74
75 /*---------------------------------------------------------------------------------------------------------------------------------------------------
76 * Change hardware pin here:
77 *---------------------------------------------------------------------------------------------------------------------------------------------------
78 */
79 #if defined (__AVR_ATmega32__) || defined (__AVR_ATmega644P__)
80 #define IRSND_PORT PORTD // port D
81 #define IRSND_DDR DDRD // ddr D
82 #define IRSND_BIT 7 // OC2A
83 #else
84 #define IRSND_PORT PORTB // port B
85 #define IRSND_DDR DDRB // ddr B
86 #define IRSND_BIT 3 // OC2A
87 #endif // __AVR...
88
89
90 #define SIRCS_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * SIRCS_START_BIT_PULSE_TIME + 0.5)
91 #define SIRCS_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * SIRCS_START_BIT_PAUSE_TIME + 0.5)
92 #define SIRCS_1_PULSE_LEN (uint8_t)(F_INTERRUPTS * SIRCS_1_PULSE_TIME + 0.5)
93 #define SIRCS_0_PULSE_LEN (uint8_t)(F_INTERRUPTS * SIRCS_0_PULSE_TIME + 0.5)
94 #define SIRCS_PAUSE_LEN (uint8_t)(F_INTERRUPTS * SIRCS_PAUSE_TIME + 0.5)
95 #define SIRCS_REPETITION_LEN (uint16_t)(F_INTERRUPTS * SIRCS_REPETITION_TIME + 0.5) // use uint16_t!
96
97 #define NEC_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * NEC_START_BIT_PULSE_TIME + 0.5)
98 #define NEC_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NEC_START_BIT_PAUSE_TIME + 0.5)
99 #define NEC_PULSE_LEN (uint8_t)(F_INTERRUPTS * NEC_PULSE_TIME + 0.5)
100 #define NEC_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NEC_1_PAUSE_TIME + 0.5)
101 #define NEC_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NEC_0_PAUSE_TIME + 0.5)
102
103 #define SAMSUNG_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PULSE_TIME + 0.5)
104 #define SAMSUNG_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PAUSE_TIME + 0.5)
105 #define SAMSUNG_PULSE_LEN (uint8_t)(F_INTERRUPTS * SAMSUNG_PULSE_TIME + 0.5)
106 #define SAMSUNG_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * SAMSUNG_1_PAUSE_TIME + 0.5)
107 #define SAMSUNG_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * SAMSUNG_0_PAUSE_TIME + 0.5)
108
109 #define MATSUSHITA_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PULSE_TIME + 0.5)
110 #define MATSUSHITA_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PAUSE_TIME + 0.5)
111 #define MATSUSHITA_PULSE_LEN (uint8_t)(F_INTERRUPTS * MATSUSHITA_PULSE_TIME + 0.5)
112 #define MATSUSHITA_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * MATSUSHITA_1_PAUSE_TIME + 0.5)
113 #define MATSUSHITA_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * MATSUSHITA_0_PAUSE_TIME + 0.5)
114
115 #define RECS80_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * RECS80_START_BIT_PULSE_TIME + 0.5)
116 #define RECS80_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RECS80_START_BIT_PAUSE_TIME + 0.5)
117 #define RECS80_PULSE_LEN (uint8_t)(F_INTERRUPTS * RECS80_PULSE_TIME + 0.5)
118 #define RECS80_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RECS80_1_PAUSE_TIME + 0.5)
119 #define RECS80_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RECS80_0_PAUSE_TIME + 0.5)
120
121 #define RC5_START_BIT_LEN (uint8_t)(F_INTERRUPTS * RC5_BIT_TIME + 0.5)
122 #define RC5_BIT_LEN (uint8_t)(F_INTERRUPTS * RC5_BIT_TIME + 0.5)
123
124 #define RC6_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * RC6_START_BIT_PULSE_TIME + 0.5)
125 #define RC6_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RC6_START_BIT_PAUSE_TIME + 0.5)
126 #define RC6_TOGGLE_BIT_LEN (uint8_t)(F_INTERRUPTS * RC6_TOGGLE_BIT_TIME + 0.5)
127 #define RC6_BIT_LEN (uint8_t)(F_INTERRUPTS * RC6_BIT_TIME + 0.5)
128
129 #define DENON_PULSE_LEN (uint8_t)(F_INTERRUPTS * DENON_PULSE_TIME + 0.5)
130 #define DENON_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * DENON_1_PAUSE_TIME + 0.5)
131 #define DENON_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * DENON_0_PAUSE_TIME + 0.5)
132 #define DENON_REPETITION_LEN (uint16_t)(F_INTERRUPTS * DENON_REPETITION_TIME + 0.5) // use uint16_t!
133
134 #define RECS80EXT_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PULSE_TIME + 0.5)
135 #define RECS80EXT_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PAUSE_TIME + 0.5)
136 #define RECS80EXT_PULSE_LEN (uint8_t)(F_INTERRUPTS * RECS80EXT_PULSE_TIME + 0.5)
137 #define RECS80EXT_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RECS80EXT_1_PAUSE_TIME + 0.5)
138 #define RECS80EXT_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RECS80EXT_0_PAUSE_TIME + 0.5)
139
140 #define NUBERT_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * NUBERT_START_BIT_PULSE_TIME + 0.5)
141 #define NUBERT_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NUBERT_START_BIT_PAUSE_TIME + 0.5)
142 #define NUBERT_1_PULSE_LEN (uint8_t)(F_INTERRUPTS * NUBERT_1_PULSE_TIME + 0.5)
143 #define NUBERT_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NUBERT_1_PAUSE_TIME + 0.5)
144 #define NUBERT_0_PULSE_LEN (uint8_t)(F_INTERRUPTS * NUBERT_0_PULSE_TIME + 0.5)
145 #define NUBERT_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NUBERT_0_PAUSE_TIME + 0.5)
146 #define NUBERT_REPETITION_LEN (uint16_t)(F_INTERRUPTS * NUBERT_REPETITION_TIME + 0.5) // use uint16_t!
147
148 #define BANG_OLUFSEN_START_BIT1_PULSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT1_PULSE_TIME + 0.5)
149 #define BANG_OLUFSEN_START_BIT1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT1_PAUSE_TIME + 0.5)
150 #define BANG_OLUFSEN_START_BIT2_PULSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT2_PULSE_TIME + 0.5)
151 #define BANG_OLUFSEN_START_BIT2_PAUSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT2_PAUSE_TIME + 0.5)
152 #define BANG_OLUFSEN_START_BIT3_PULSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT3_PULSE_TIME + 0.5)
153 #define BANG_OLUFSEN_START_BIT3_PAUSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT3_PAUSE_TIME + 0.5)
154 #define BANG_OLUFSEN_PULSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_PULSE_TIME + 0.5)
155 #define BANG_OLUFSEN_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_1_PAUSE_TIME + 0.5)
156 #define BANG_OLUFSEN_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_0_PAUSE_TIME + 0.5)
157 #define BANG_OLUFSEN_R_PAUSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_R_PAUSE_TIME + 0.5)
158 #define BANG_OLUFSEN_TRAILER_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_TRAILER_BIT_PAUSE_TIME + 0.5)
159
160 #define IRSND_FREQ_32_KHZ (uint8_t) ((F_CPU / 32000 / 2) - 1)
161 #define IRSND_FREQ_36_KHZ (uint8_t) ((F_CPU / 36000 / 2) - 1)
162 #define IRSND_FREQ_38_KHZ (uint8_t) ((F_CPU / 38000 / 2) - 1)
163 #define IRSND_FREQ_40_KHZ (uint8_t) ((F_CPU / 40000 / 2) - 1)
164 #define IRSND_FREQ_56_KHZ (uint8_t) ((F_CPU / 56000 / 2) - 1)
165 #define IRSND_FREQ_455_KHZ (uint8_t) ((F_CPU / 455000 / 2) - 1)
166
167 static volatile uint8_t irsnd_busy;
168 static volatile uint8_t irsnd_protocol;
169 static volatile uint8_t irsnd_buffer[5];
170 static volatile uint8_t irsnd_is_on = FALSE;
171
172 /*---------------------------------------------------------------------------------------------------------------------------------------------------
173 * Switch PWM on
174 * @details Switches PWM on with a narrow spike on all 3 channels -> leds glowing
175 *---------------------------------------------------------------------------------------------------------------------------------------------------
176 */
177 static void
178 irsnd_on (void)
179 {
180 if (! irsnd_is_on)
181 {
182 #ifndef DEBUG
183 #if defined (__AVR_ATmega32__)
184 TCCR2 |= (1<<COM20)|(1<<WGM21); // = 0x42: toggle OC2A on compare match, clear Timer 2 at compare match OCR2A
185 #else
186 TCCR2A |= (1<<COM2A0)|(1<<WGM21); // = 0x42: toggle OC2A on compare match, clear Timer 2 at compare match OCR2A
187 #endif // __AVR...
188 #endif // DEBUG
189 irsnd_is_on = TRUE;
190 }
191 }
192
193 /*---------------------------------------------------------------------------------------------------------------------------------------------------
194 * Switch PWM off
195 * @details Switches PWM off
196 *---------------------------------------------------------------------------------------------------------------------------------------------------
197 */
198 static void
199 irsnd_off (void)
200 {
201 if (irsnd_is_on)
202 {
203 #ifndef DEBUG
204 #if defined (__AVR_ATmega32__)
205 TCCR2 &= ~(1<<COM20); // normal port operation, OC2A disconnected.
206 #else
207 TCCR2A &= ~(1<<COM2A0); // normal port operation, OC2A disconnected.
208 #endif // __AVR...
209 IRSND_PORT &= ~(1<<IRSND_BIT); // set IRSND_BIT to low
210 #endif // DEBUG
211 irsnd_is_on = FALSE;
212 }
213 }
214
215 /*---------------------------------------------------------------------------------------------------------------------------------------------------
216 * Set PWM frequency
217 * @details sets pwm frequency
218 *---------------------------------------------------------------------------------------------------------------------------------------------------
219 */
220 static void
221 irsnd_set_freq (uint8_t freq)
222 {
223 #ifndef DEBUG
224 #if defined (__AVR_ATmega32__)
225 OCR2 = freq;
226 #else
227 OCR2A = freq;
228 #endif // __AVR...
229 #endif // DEBUG
230 }
231
232 /*---------------------------------------------------------------------------------------------------------------------------------------------------
233 * Initialize the PWM
234 * @details Configures 0CR0A, 0CR0B and 0CR2B as PWM channels
235 *---------------------------------------------------------------------------------------------------------------------------------------------------
236 */
237 void
238 irsnd_init (void)
239 {
240 #ifndef DEBUG
241 IRSND_PORT &= ~(1<<IRSND_BIT); // set IRSND_BIT to low
242 IRSND_DDR |= (1<<IRSND_BIT); // set IRSND_BIT to output
243
244 #if defined (__AVR_ATmega32__)
245 TCCR2 = (1<<WGM21); // CTC mode
246 TCCR2 |= (1<<CS20); // 0x01, start Timer 2, no prescaling
247 #else
248 TCCR2A = (1<<WGM21); // CTC mode
249 TCCR2B |= (1<<CS20); // 0x01, start Timer 2, no prescaling
250 #endif // __AVR...
251
252 irsnd_set_freq (IRSND_FREQ_36_KHZ); // default frequency
253 #endif // DEBUG
254 }
255
256 uint8_t
257 irsnd_is_busy (void)
258 {
259 return irsnd_busy;
260 }
261
262 static uint16_t
263 bitsrevervse (uint16_t x, uint8_t len)
264 {
265 uint16_t xx = 0;
266
267 while(len)
268 {
269 xx <<= 1;
270 if (x & 1)
271 {
272 xx |= 1;
273 }
274 x >>= 1;
275 len--;
276 }
277 return xx;
278 }
279
280
281 uint8_t
282 irsnd_send_data (IRMP_DATA * irmp_data_p)
283 {
284 #if IRSND_SUPPORT_RECS80_PROTOCOL == 1
285 static uint8_t toggle_bit_recs80;
286 #endif
287 #if IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1
288 static uint8_t toggle_bit_recs80ext;
289 #endif
290 #if IRSND_SUPPORT_RC5_PROTOCOL == 1
291 static uint8_t toggle_bit_rc5;
292 #endif
293 uint16_t address;
294 uint16_t command;
295
296 while (irsnd_busy)
297 {
298 ;
299 }
300
301 irsnd_protocol = irmp_data_p->protocol;
302
303 switch (irsnd_protocol)
304 {
305 #if IRSND_SUPPORT_SIRCS_PROTOCOL == 1
306 case IRMP_SIRCS_PROTOCOL:
307 {
308 command = bitsrevervse (irmp_data_p->command, SIRCS_MINIMUM_DATA_LEN);
309
310 irsnd_protocol = irmp_data_p->protocol;
311 irsnd_buffer[0] = (command & 0x0FF0) >> 4; // CCCCCCCC
312 irsnd_buffer[1] = (command & 0x000F) << 4; // CCCC0000
313 irsnd_busy = TRUE;
314 break;
315 }
316 #endif
317 #if IRSND_SUPPORT_NEC_PROTOCOL == 1
318 case IRMP_NEC_PROTOCOL:
319 {
320 address = bitsrevervse (irmp_data_p->address, NEC_ADDRESS_LEN);
321 command = bitsrevervse (irmp_data_p->command, NEC_COMMAND_LEN);
322
323 irsnd_protocol = irmp_data_p->protocol;
324 irsnd_buffer[0] = (address & 0xFF00) >> 8; // AAAAAAAA
325 irsnd_buffer[1] = (address & 0x00FF); // AAAAAAAA
326 irsnd_buffer[2] = (command & 0xFF00) >> 8; // CCCCCCCC
327 irsnd_buffer[3] = ~((command & 0xFF00) >> 8); // cccccccc
328 irsnd_busy = TRUE;
329 break;
330 }
331 #endif
332 #if IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1
333 case IRMP_SAMSUNG_PROTOCOL:
334 {
335 address = bitsrevervse (irmp_data_p->address, SAMSUNG_ADDRESS_LEN);
336 command = bitsrevervse (irmp_data_p->command, SAMSUNG_COMMAND_LEN);
337
338 irsnd_protocol = irmp_data_p->protocol;
339 irsnd_buffer[0] = (address & 0xFF00) >> 8; // AAAAAAAA
340 irsnd_buffer[1] = (address & 0x00FF); // AAAAAAAA
341 irsnd_buffer[2] = (command & 0x00F0) | ((command & 0xF000) >> 12); // IIIICCCC
342 irsnd_buffer[3] = ((command & 0x0F00) >> 4) | ((~(command & 0xF000) >> 12) & 0x0F); // CCCCcccc
343 irsnd_buffer[4] = (~(command & 0x0F00) >> 4) & 0xF0; // cccc0000
344 irsnd_busy = TRUE;
345 break;
346 }
347 case IRMP_SAMSUNG32_PROTOCOL:
348 {
349 address = bitsrevervse (irmp_data_p->address, SAMSUNG_ADDRESS_LEN);
350 command = bitsrevervse (irmp_data_p->command, SAMSUNG32_COMMAND_LEN);
351
352 irsnd_protocol = irmp_data_p->protocol;
353 irsnd_buffer[0] = (address & 0xFF00) >> 8; // AAAAAAAA
354 irsnd_buffer[1] = (address & 0x00FF); // AAAAAAAA
355 irsnd_buffer[2] = (command & 0xFF00) >> 8; // CCCCCCCC
356 irsnd_buffer[3] = (command & 0x00FF); // CCCCCCCC
357 irsnd_busy = TRUE;
358 break;
359 }
360 #endif
361 #if IRSND_SUPPORT_MATSUSHITA_PROTOCOL == 1
362 case IRMP_MATSUSHITA_PROTOCOL:
363 {
364 address = bitsrevervse (irmp_data_p->address, MATSUSHITA_ADDRESS_LEN);
365 command = bitsrevervse (irmp_data_p->command, MATSUSHITA_COMMAND_LEN);
366
367 irsnd_protocol = irmp_data_p->protocol;
368 irsnd_buffer[0] = (command & 0x0FF0) >> 4; // CCCCCCCC
369 irsnd_buffer[1] = ((command & 0x000F) << 4) | ((address & 0x0F00) >> 8); // CCCCAAAA
370 irsnd_buffer[2] = (address & 0x00FF); // AAAAAAAA
371 irsnd_busy = TRUE;
372 break;
373 }
374 #endif
375 #if IRSND_SUPPORT_RECS80_PROTOCOL == 1
376 case IRMP_RECS80_PROTOCOL:
377 {
378 toggle_bit_recs80 = toggle_bit_recs80 ? 0x00 : 0x40;
379
380 irsnd_protocol = irmp_data_p->protocol;
381 irsnd_buffer[0] = 0x80 | toggle_bit_recs80 | ((irmp_data_p->address & 0x0007) << 3) |
382 ((irmp_data_p->command & 0x0038) >> 3); // STAAACCC
383 irsnd_buffer[1] = (irmp_data_p->command & 0x07) << 5; // CCC00000
384 irsnd_busy = TRUE;
385 break;
386 }
387 #endif
388 #if IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1
389 case IRMP_RECS80EXT_PROTOCOL:
390 {
391 toggle_bit_recs80ext = toggle_bit_recs80ext ? 0x00 : 0x40;
392
393 irsnd_protocol = irmp_data_p->protocol;
394 irsnd_buffer[0] = 0x80 | toggle_bit_recs80ext | ((irmp_data_p->address & 0x000F) << 2) |
395 ((irmp_data_p->command & 0x0030) >> 4); // STAAAACC
396 irsnd_buffer[1] = (irmp_data_p->command & 0x0F) << 4; // CCCC0000
397 irsnd_busy = TRUE;
398 break;
399 }
400 #endif
401 #if IRSND_SUPPORT_RC5_PROTOCOL == 1
402 case IRMP_RC5_PROTOCOL:
403 {
404 toggle_bit_rc5 = toggle_bit_rc5 ? 0x00 : 0x40;
405
406 irsnd_protocol = irmp_data_p->protocol;
407 irsnd_buffer[0] = ((irmp_data_p->command & 0x40) ? 0x00 : 0x80) | toggle_bit_rc5 |
408 ((irmp_data_p->address & 0x001F) << 1) | ((irmp_data_p->command & 0x20) >> 5); // CTAAAAAC
409 irsnd_buffer[1] = (irmp_data_p->command & 0x1F) << 3; // CCCCC000
410 irsnd_busy = TRUE;
411 break;
412 }
413 #endif
414 #if IRSND_SUPPORT_DENON_PROTOCOL == 1
415 case IRMP_DENON_PROTOCOL:
416 {
417 irsnd_protocol = irmp_data_p->protocol;
418 irsnd_buffer[0] = ((irmp_data_p->address & 0x1F) << 3) | ((irmp_data_p->command & 0x0380) >> 7); // AAAAACCC
419 irsnd_buffer[1] = (irmp_data_p->command & 0x7F) << 1; // CCCCCCC0
420 irsnd_buffer[2] = ((irmp_data_p->address & 0x1F) << 3) | (((~irmp_data_p->command) & 0x0380) >> 7); // AAAAACCC
421 irsnd_buffer[3] = (~(irmp_data_p->command) & 0x7F) << 1; // CCCCCCC0
422 irsnd_busy = TRUE;
423 break;
424 }
425 #endif
426 #if IRSND_SUPPORT_NUBERT_PROTOCOL == 1
427 case IRMP_NUBERT_PROTOCOL:
428 {
429 irsnd_protocol = irmp_data_p->protocol;
430 irsnd_buffer[0] = irmp_data_p->command >> 2; // CCCCCCCC
431 irsnd_buffer[1] = (irmp_data_p->command & 0x0003) << 6; // CC000000
432 irsnd_busy = TRUE;
433 break;
434 }
435 #endif
436 #if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1
437 case IRMP_BANG_OLUFSEN_PROTOCOL:
438 {
439 irsnd_protocol = irmp_data_p->protocol;
440 irsnd_buffer[0] = irmp_data_p->command >> 11; // SXSCCCCC
441 irsnd_buffer[1] = irmp_data_p->command >> 3; // CCCCCCCC
442 irsnd_buffer[2] = (irmp_data_p->command & 0x0007) << 5; // CCC00000
443 irsnd_busy = TRUE;
444 break;
445 }
446 #endif
447 default:
448 {
449 break;
450 }
451 }
452
453 return irsnd_busy;
454 }
455
456 /*---------------------------------------------------------------------------------------------------------------------------------------------------
457 * ISR routine
458 * @details ISR routine, called 10000 times per second
459 *---------------------------------------------------------------------------------------------------------------------------------------------------
460 */
461 uint8_t
462 irsnd_ISR (void)
463 {
464 static uint8_t current_bit = 0xFF;
465 static uint8_t pulse_counter;
466 static uint8_t pause_counter;
467 static uint8_t startbit_pulse_len;
468 static uint8_t startbit_pause_len;
469 static uint8_t pulse_1_len;
470 static uint8_t pause_1_len;
471 static uint8_t pulse_0_len;
472 static uint8_t pause_0_len;
473 static uint8_t has_stop_bit;
474 static uint8_t new_frame = TRUE;
475 static uint8_t complete_data_len;
476 static uint8_t n_frames; // number of repetitions
477 static uint8_t frame_counter; // repetition counter
478 static uint16_t repetition_pause; // pause before repetition, uint16_t!
479 static uint16_t repetition_pause_counter; // pause before repetition, uint16_t!
480 #if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1
481 static uint8_t last_bit_value;
482 #endif
483 static uint8_t pulse_len = 0xFF;
484 static uint8_t pause_len = 0xFF;
485
486 if (irsnd_busy)
487 {
488 if (current_bit == 0xFF && new_frame) // start of transmission...
489 {
490 if (frame_counter > 0)
491 {
492 repetition_pause_counter++;
493
494 if (repetition_pause_counter >= repetition_pause)
495 {
496 repetition_pause_counter = 0;
497
498 if (irsnd_protocol == IRMP_DENON_PROTOCOL)
499 {
500 current_bit = 16;
501 complete_data_len = 2 * DENON_COMPLETE_DATA_LEN + 1;
502 }
503 }
504 else
505 {
506 #ifdef DEBUG
507 if (irsnd_is_on)
508 {
509 putchar ('0');
510 }
511 else
512 {
513 putchar ('1');
514 }
515 #endif
516 return irsnd_busy;
517 }
518 }
519 else
520 {
521 pulse_counter = 0;
522 pause_counter = 0;
523
524 switch (irsnd_protocol)
525 {
526 #if IRSND_SUPPORT_SIRCS_PROTOCOL == 1
527 case IRMP_SIRCS_PROTOCOL:
528 {
529 startbit_pulse_len = SIRCS_START_BIT_PULSE_LEN;
530 startbit_pause_len = SIRCS_START_BIT_PAUSE_LEN;
531 pulse_1_len = SIRCS_1_PULSE_LEN;
532 pause_1_len = SIRCS_PAUSE_LEN;
533 pulse_0_len = SIRCS_0_PULSE_LEN;
534 pause_0_len = SIRCS_PAUSE_LEN;
535 has_stop_bit = SIRCS_STOP_BIT;
536 complete_data_len = SIRCS_MINIMUM_DATA_LEN;
537 n_frames = SIRCS_REPETITION_CNT;
538 repetition_pause = SIRCS_REPETITION_LEN; // 45 ms pause
539 irsnd_set_freq (IRSND_FREQ_40_KHZ);
540 break;
541 }
542 #endif
543 #if IRSND_SUPPORT_NEC_PROTOCOL == 1
544 case IRMP_NEC_PROTOCOL:
545 {
546 startbit_pulse_len = NEC_START_BIT_PULSE_LEN;
547 startbit_pause_len = NEC_START_BIT_PAUSE_LEN;
548 pulse_1_len = NEC_PULSE_LEN;
549 pause_1_len = NEC_1_PAUSE_LEN;
550 pulse_0_len = NEC_PULSE_LEN;
551 pause_0_len = NEC_0_PAUSE_LEN;
552 has_stop_bit = NEC_STOP_BIT;
553 complete_data_len = NEC_COMPLETE_DATA_LEN;
554 n_frames = 1;
555 irsnd_set_freq (IRSND_FREQ_38_KHZ);
556 break;
557 }
558 #endif
559 #if IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1
560 case IRMP_SAMSUNG_PROTOCOL:
561 {
562 startbit_pulse_len = SAMSUNG_START_BIT_PULSE_LEN;
563 startbit_pause_len = SAMSUNG_START_BIT_PAUSE_LEN;
564 pulse_1_len = SAMSUNG_PULSE_LEN;
565 pause_1_len = SAMSUNG_1_PAUSE_LEN;
566 pulse_0_len = SAMSUNG_PULSE_LEN;
567 pause_0_len = SAMSUNG_0_PAUSE_LEN;
568 has_stop_bit = SAMSUNG_STOP_BIT;
569 complete_data_len = SAMSUNG_COMPLETE_DATA_LEN;
570 n_frames = 1;
571 irsnd_set_freq (IRSND_FREQ_38_KHZ);
572 break;
573 }
574
575 case IRMP_SAMSUNG32_PROTOCOL:
576 {
577 startbit_pulse_len = SAMSUNG_START_BIT_PULSE_LEN;
578 startbit_pause_len = SAMSUNG_START_BIT_PAUSE_LEN;
579 pulse_1_len = SAMSUNG_PULSE_LEN;
580 pause_1_len = SAMSUNG_1_PAUSE_LEN;
581 pulse_0_len = SAMSUNG_PULSE_LEN;
582 pause_0_len = SAMSUNG_0_PAUSE_LEN;
583 has_stop_bit = SAMSUNG_STOP_BIT;
584 complete_data_len = SAMSUNG32_COMPLETE_DATA_LEN;
585 n_frames = 1;
586 irsnd_set_freq (IRSND_FREQ_38_KHZ);
587 break;
588 }
589 #endif
590 #if IRSND_SUPPORT_MATSUSHITA_PROTOCOL == 1
591 case IRMP_MATSUSHITA_PROTOCOL:
592 {
593 startbit_pulse_len = MATSUSHITA_START_BIT_PULSE_LEN;
594 startbit_pause_len = MATSUSHITA_START_BIT_PAUSE_LEN;
595 pulse_1_len = MATSUSHITA_PULSE_LEN;
596 pause_1_len = MATSUSHITA_1_PAUSE_LEN;
597 pulse_0_len = MATSUSHITA_PULSE_LEN;
598 pause_0_len = MATSUSHITA_0_PAUSE_LEN;
599 has_stop_bit = MATSUSHITA_STOP_BIT;
600 complete_data_len = MATSUSHITA_COMPLETE_DATA_LEN;
601 n_frames = 1;
602 irsnd_set_freq (IRSND_FREQ_36_KHZ);
603 break;
604 }
605 #endif
606 #if IRSND_SUPPORT_RECS80_PROTOCOL == 1
607 case IRMP_RECS80_PROTOCOL:
608 {
609 startbit_pulse_len = RECS80_START_BIT_PULSE_LEN;
610 startbit_pause_len = RECS80_START_BIT_PAUSE_LEN;
611 pulse_1_len = RECS80_PULSE_LEN;
612 pause_1_len = RECS80_1_PAUSE_LEN;
613 pulse_0_len = RECS80_PULSE_LEN;
614 pause_0_len = RECS80_0_PAUSE_LEN;
615 has_stop_bit = RECS80_STOP_BIT;
616 complete_data_len = RECS80_COMPLETE_DATA_LEN;
617 n_frames = 1;
618 irsnd_set_freq (IRSND_FREQ_38_KHZ);
619 break;
620 }
621 #endif
622 #if IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1
623 case IRMP_RECS80EXT_PROTOCOL:
624 {
625 startbit_pulse_len = RECS80EXT_START_BIT_PULSE_LEN;
626 startbit_pause_len = RECS80EXT_START_BIT_PAUSE_LEN;
627 pulse_1_len = RECS80EXT_PULSE_LEN;
628 pause_1_len = RECS80EXT_1_PAUSE_LEN;
629 pulse_0_len = RECS80EXT_PULSE_LEN;
630 pause_0_len = RECS80EXT_0_PAUSE_LEN;
631 has_stop_bit = RECS80EXT_STOP_BIT;
632 complete_data_len = RECS80EXT_COMPLETE_DATA_LEN;
633 n_frames = 1;
634 irsnd_set_freq (IRSND_FREQ_38_KHZ);
635 break;
636 }
637 #endif
638 #if IRSND_SUPPORT_RC5_PROTOCOL == 1
639 case IRMP_RC5_PROTOCOL:
640 {
641 startbit_pulse_len = RC5_BIT_LEN;
642 startbit_pause_len = RC5_BIT_LEN;
643 pulse_1_len = RC5_BIT_LEN;
644 pause_1_len = RC5_BIT_LEN;
645 pulse_0_len = RC5_BIT_LEN;
646 pause_0_len = RC5_BIT_LEN;
647 has_stop_bit = RC5_STOP_BIT;
648 complete_data_len = RC5_COMPLETE_DATA_LEN;
649 n_frames = 1;
650 irsnd_set_freq (IRSND_FREQ_36_KHZ);
651 break;
652 }
653 #endif
654 #if IRSND_SUPPORT_DENON_PROTOCOL == 1
655 case IRMP_DENON_PROTOCOL:
656 {
657 startbit_pulse_len = 0x00;
658 startbit_pause_len = 0x00;
659 pulse_1_len = DENON_PULSE_LEN;
660 pause_1_len = DENON_1_PAUSE_LEN;
661 pulse_0_len = DENON_PULSE_LEN;
662 pause_0_len = DENON_0_PAUSE_LEN;
663 has_stop_bit = DENON_STOP_BIT;
664 complete_data_len = DENON_COMPLETE_DATA_LEN;
665 n_frames = 2;
666 repetition_pause = DENON_REPETITION_LEN; // 65 ms pause after 1st frame (15 bits)
667 irsnd_set_freq (IRSND_FREQ_32_KHZ);
668 break;
669 }
670 #endif
671 #if IRSND_SUPPORT_NUBERT_PROTOCOL == 1
672 case IRMP_NUBERT_PROTOCOL:
673 {
674 startbit_pulse_len = NUBERT_START_BIT_PULSE_LEN;
675 startbit_pause_len = NUBERT_START_BIT_PAUSE_LEN;
676 pulse_1_len = NUBERT_1_PULSE_LEN;
677 pause_1_len = NUBERT_1_PAUSE_LEN;
678 pulse_0_len = NUBERT_0_PULSE_LEN;
679 pause_0_len = NUBERT_0_PAUSE_LEN;
680 has_stop_bit = NUBERT_STOP_BIT;
681 complete_data_len = NUBERT_COMPLETE_DATA_LEN;
682 n_frames = 2;
683 repetition_pause = NUBERT_REPETITION_LEN; // 35 ms pause
684 irsnd_set_freq (IRSND_FREQ_36_KHZ);
685 break;
686 }
687 #endif
688 #if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1
689 case IRMP_BANG_OLUFSEN_PROTOCOL:
690 {
691 startbit_pulse_len = BANG_OLUFSEN_START_BIT1_PULSE_LEN;
692 startbit_pause_len = BANG_OLUFSEN_START_BIT1_PAUSE_LEN;
693 pulse_1_len = BANG_OLUFSEN_PULSE_LEN;
694 pause_1_len = BANG_OLUFSEN_1_PAUSE_LEN;
695 pulse_0_len = BANG_OLUFSEN_PULSE_LEN;
696 pause_0_len = BANG_OLUFSEN_0_PAUSE_LEN;
697 has_stop_bit = BANG_OLUFSEN_STOP_BIT;
698 complete_data_len = BANG_OLUFSEN_COMPLETE_DATA_LEN;
699 n_frames = 1;
700 last_bit_value = 0;
701 irsnd_set_freq (IRSND_FREQ_455_KHZ);
702 break;
703 }
704 #endif
705 default:
706 {
707 irsnd_busy = FALSE;
708 break;
709 }
710 }
711 }
712 }
713
714 if (irsnd_busy)
715 {
716 new_frame = FALSE;
717 switch (irsnd_protocol)
718 {
719 #if IRSND_SUPPORT_SIRCS_PROTOCOL == 1
720 case IRMP_SIRCS_PROTOCOL:
721 #endif
722 #if IRSND_SUPPORT_NEC_PROTOCOL == 1
723 case IRMP_NEC_PROTOCOL:
724 #endif
725 #if IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1
726 case IRMP_SAMSUNG_PROTOCOL:
727 case IRMP_SAMSUNG32_PROTOCOL:
728 #endif
729 #if IRSND_SUPPORT_MATSUSHITA_PROTOCOL == 1
730 case IRMP_MATSUSHITA_PROTOCOL:
731 #endif
732 #if IRSND_SUPPORT_RECS80_PROTOCOL == 1
733 case IRMP_RECS80_PROTOCOL:
734 #endif
735 #if IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1
736 case IRMP_RECS80EXT_PROTOCOL:
737 #endif
738 #if IRSND_SUPPORT_DENON_PROTOCOL == 1
739 case IRMP_DENON_PROTOCOL:
740 #endif
741 #if IRSND_SUPPORT_NUBERT_PROTOCOL == 1
742 case IRMP_NUBERT_PROTOCOL:
743 #endif
744 #if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1
745 case IRMP_BANG_OLUFSEN_PROTOCOL:
746 #endif
747 {
748 if (pulse_counter == 0)
749 {
750 if (current_bit == 0xFF) // send start bit
751 {
752 pulse_len = startbit_pulse_len;
753 pause_len = startbit_pause_len;
754 }
755 else if (current_bit < complete_data_len) // send n'th bit
756 {
757 #if IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1
758 if (irsnd_protocol == IRMP_SAMSUNG_PROTOCOL)
759 {
760 if (current_bit < SAMSUNG_ADDRESS_LEN) // send address bits
761 {
762 pulse_len = SAMSUNG_PULSE_LEN;
763 pause_len = (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8)))) ?
764 SAMSUNG_1_PAUSE_LEN : SAMSUNG_0_PAUSE_LEN;
765 }
766 else if (current_bit == SAMSUNG_ADDRESS_LEN) // send SYNC bit (16th bit)
767 {
768 pulse_len = SAMSUNG_PULSE_LEN;
769 pause_len = SAMSUNG_START_BIT_PAUSE_LEN;
770 }
771 else if (current_bit < SAMSUNG_COMPLETE_DATA_LEN) // send n'th bit
772 {
773 uint8_t cur_bit = current_bit - 1; // sync skipped, offset = -1 !
774
775 pulse_len = SAMSUNG_PULSE_LEN;
776 pause_len = (irsnd_buffer[cur_bit / 8] & (1<<(7-(cur_bit % 8)))) ?
777 SAMSUNG_1_PAUSE_LEN : SAMSUNG_0_PAUSE_LEN;
778 }
779 }
780 else
781 #endif
782
783 #if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1
784 if (irsnd_protocol == IRMP_BANG_OLUFSEN_PROTOCOL)
785 {
786 if (current_bit == 0) // send 2nd start bit
787 {
788 pulse_len = BANG_OLUFSEN_START_BIT2_PULSE_LEN;
789 pause_len = BANG_OLUFSEN_START_BIT2_PAUSE_LEN;
790 }
791 else if (current_bit == 1) // send 3rd start bit
792 {
793 pulse_len = BANG_OLUFSEN_START_BIT3_PULSE_LEN;
794 pause_len = BANG_OLUFSEN_START_BIT3_PAUSE_LEN;
795 }
796 else if (current_bit == 2) // send 4th start bit
797 {
798 pulse_len = BANG_OLUFSEN_START_BIT2_PULSE_LEN;
799 pause_len = BANG_OLUFSEN_START_BIT2_PAUSE_LEN;
800 }
801 else if (current_bit == 19) // send trailer bit
802 {
803 pulse_len = BANG_OLUFSEN_PULSE_LEN;
804 pause_len = BANG_OLUFSEN_TRAILER_BIT_PAUSE_LEN;
805 }
806 else if (current_bit < BANG_OLUFSEN_COMPLETE_DATA_LEN) // send n'th bit
807 {
808 uint8_t cur_bit_value = (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8)))) ? 1 : 0;
809 pulse_len = BANG_OLUFSEN_PULSE_LEN;
810
811 if (cur_bit_value == last_bit_value)
812 {
813 pause_len = BANG_OLUFSEN_R_PAUSE_LEN;
814 }
815 else
816 {
817 pause_len = cur_bit_value ? BANG_OLUFSEN_1_PAUSE_LEN : BANG_OLUFSEN_0_PAUSE_LEN;
818 last_bit_value = cur_bit_value;
819 }
820 }
821 }
822 else
823 #endif
824 if (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8))))
825 {
826 pulse_len = pulse_1_len;
827 pause_len = pause_1_len;
828 }
829 else
830 {
831 pulse_len = pulse_0_len;
832 pause_len = pause_0_len;
833 }
834 }
835 else if (has_stop_bit) // send stop bit
836 {
837 pulse_len = pulse_0_len;
838
839 if (frame_counter < n_frames)
840 {
841 pause_len = pause_0_len;
842 }
843 else
844 {
845 pause_len = 255; // last frame: pause of 255
846 }
847 }
848 }
849
850 if (pulse_counter < pulse_len)
851 {
852 if (pulse_counter == 0)
853 {
854 irsnd_on ();
855 }
856 pulse_counter++;
857 }
858 else if (pause_counter < pause_len)
859 {
860 if (pause_counter == 0)
861 {
862 irsnd_off ();
863 }
864 pause_counter++;
865 }
866 else
867 {
868 current_bit++;
869
870 if (current_bit >= complete_data_len + has_stop_bit)
871 {
872 current_bit = 0xFF;
873 frame_counter++;
874
875 if (frame_counter == n_frames)
876 {
877 irsnd_busy = FALSE;
878 frame_counter = 0;
879 }
880 new_frame = TRUE;
881 }
882
883 pulse_counter = 0;
884 pause_counter = 0;
885 }
886 break;
887 }
888 #if IRSND_SUPPORT_RC5_PROTOCOL == 1
889 case IRMP_RC5_PROTOCOL:
890 {
891 uint8_t first_pulse;
892 uint8_t next_bit = FALSE;
893
894 if (current_bit == 0xFF) // 1 start bit
895 {
896 first_pulse = FALSE;
897 }
898 else // send n'th bit
899 {
900 first_pulse = (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8)))) ? FALSE : TRUE;
901 }
902
903 if (first_pulse)
904 {
905 if (pulse_counter < RC5_BIT_LEN)
906 {
907 if (pulse_counter == 0)
908 {
909 irsnd_on ();
910 }
911 pulse_counter++;
912 }
913 else if (pause_counter < RC5_BIT_LEN)
914 {
915 if (pause_counter == 0)
916 {
917 irsnd_off ();
918 }
919 pause_counter++;
920 }
921 else
922 {
923 next_bit = TRUE;
924 }
925 }
926 else
927 {
928 if (pause_counter < RC5_BIT_LEN)
929 {
930 if (pause_counter == 0)
931 {
932 irsnd_off ();
933 }
934 pause_counter++;
935 }
936 else if (pulse_counter < RC5_BIT_LEN)
937 {
938 if (pulse_counter == 0)
939 {
940 irsnd_on ();
941 }
942 pulse_counter++;
943 }
944 else
945 {
946 next_bit = TRUE;
947 }
948 }
949
950 if (next_bit)
951 {
952 current_bit++;
953
954 if (current_bit >= RC5_COMPLETE_DATA_LEN)
955 {
956 current_bit = 0xFF;
957 irsnd_busy = FALSE;
958 new_frame = TRUE;
959 irsnd_off ();
960 }
961
962 pulse_counter = 0;
963 pause_counter = 0;
964 }
965 break;
966 }
967 #endif // IRSND_SUPPORT_RC5_PROTOCOL
968 default:
969 {
970 irsnd_busy = FALSE;
971 break;
972 }
973 }
974 }
975 }
976
977 #ifdef DEBUG
978 if (irsnd_is_on)
979 {
980 putchar ('0');
981 }
982 else
983 {
984 putchar ('1');
985 }
986 #endif
987
988 return irsnd_busy;
989 }
990
991 #ifdef DEBUG
992
993 // main function - for unix/linux + windows only!
994 // AVR: see main.c!
995 // Compile it under linux with:
996 // cc irsnd.c -o irsnd
997 //
998 // usage: ./irsnd protocol hex-address hex-command >filename
999
1000 int
1001 main (int argc, char ** argv)
1002 {
1003 int idx;
1004 int cnt;
1005 int protocol;
1006 int address;
1007 int command;
1008 int repeat = 1;
1009 IRMP_DATA irmp_data;
1010
1011 if (argc != 4)
1012 {
1013 fprintf (stderr, "usage: %s protocol hex-address hex-command > filename\n", argv[0]);
1014 return 1;
1015 }
1016
1017 if (sscanf (argv[1], "%d", &protocol) == 1 &&
1018 sscanf (argv[2], "%x", &address) == 1 &&
1019 sscanf (argv[3], "%x", &command) == 1)
1020 {
1021 irmp_data.protocol = protocol;
1022 irmp_data.address = address;
1023 irmp_data.command = command;
1024
1025 irsnd_init ();
1026
1027 for (cnt = 0; cnt < repeat; cnt++)
1028 {
1029 (void) irsnd_send_data (&irmp_data);
1030
1031 for (idx = 0; idx < 3000; idx++)
1032 {
1033 irsnd_ISR ();
1034 }
1035 }
1036
1037 putchar ('\n');
1038 }
1039 else
1040 {
1041 fprintf (stderr, "%s: wrong arguments\n", argv[0]);
1042 return 1;
1043 }
1044 return 0;
1045 }
1046
1047 #endif // DEBUG