1 /*---------------------------------------------------------------------------------------------------------------------------------------------------
4 * Copyright (c) 2010 Frank Meyer - frank(at)fli4l.de
6 * $Id: irsnd.c,v 1.9 2010/04/28 14:58:59 fm Exp $
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 *---------------------------------------------------------------------------------------------------------------------------------------------------
15 #ifdef unix // test/debug on linux/unix
23 #define F_CPU 8000000L
27 #ifdef WIN32 // test/debug on windows
29 #define F_CPU 8000000L
30 typedef unsigned char uint8_t;
31 typedef unsigned short uint16_t;
43 #include <util/delay.h>
44 #include <avr/pgmspace.h>
51 #include "irsndconfig.h"
54 #define SIRCS_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * SIRCS_START_BIT_PULSE_TIME + 0.5)
55 #define SIRCS_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * SIRCS_START_BIT_PAUSE_TIME + 0.5)
56 #define SIRCS_1_PULSE_LEN (uint8_t)(F_INTERRUPTS * SIRCS_1_PULSE_TIME + 0.5)
57 #define SIRCS_0_PULSE_LEN (uint8_t)(F_INTERRUPTS * SIRCS_0_PULSE_TIME + 0.5)
58 #define SIRCS_PAUSE_LEN (uint8_t)(F_INTERRUPTS * SIRCS_PAUSE_TIME + 0.5)
59 #define SIRCS_REPETITION_LEN (uint16_t)(F_INTERRUPTS * SIRCS_REPETITION_TIME + 0.5) // use uint16_t!
61 #define NEC_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * NEC_START_BIT_PULSE_TIME + 0.5)
62 #define NEC_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NEC_START_BIT_PAUSE_TIME + 0.5)
63 #define NEC_PULSE_LEN (uint8_t)(F_INTERRUPTS * NEC_PULSE_TIME + 0.5)
64 #define NEC_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NEC_1_PAUSE_TIME + 0.5)
65 #define NEC_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NEC_0_PAUSE_TIME + 0.5)
67 #define SAMSUNG_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PULSE_TIME + 0.5)
68 #define SAMSUNG_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PAUSE_TIME + 0.5)
69 #define SAMSUNG_PULSE_LEN (uint8_t)(F_INTERRUPTS * SAMSUNG_PULSE_TIME + 0.5)
70 #define SAMSUNG_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * SAMSUNG_1_PAUSE_TIME + 0.5)
71 #define SAMSUNG_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * SAMSUNG_0_PAUSE_TIME + 0.5)
73 #define MATSUSHITA_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PULSE_TIME + 0.5)
74 #define MATSUSHITA_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PAUSE_TIME + 0.5)
75 #define MATSUSHITA_PULSE_LEN (uint8_t)(F_INTERRUPTS * MATSUSHITA_PULSE_TIME + 0.5)
76 #define MATSUSHITA_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * MATSUSHITA_1_PAUSE_TIME + 0.5)
77 #define MATSUSHITA_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * MATSUSHITA_0_PAUSE_TIME + 0.5)
79 #define RECS80_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * RECS80_START_BIT_PULSE_TIME + 0.5)
80 #define RECS80_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RECS80_START_BIT_PAUSE_TIME + 0.5)
81 #define RECS80_PULSE_LEN (uint8_t)(F_INTERRUPTS * RECS80_PULSE_TIME + 0.5)
82 #define RECS80_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RECS80_1_PAUSE_TIME + 0.5)
83 #define RECS80_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RECS80_0_PAUSE_TIME + 0.5)
85 #define RC5_START_BIT_LEN (uint8_t)(F_INTERRUPTS * RC5_BIT_TIME + 0.5)
86 #define RC5_BIT_LEN (uint8_t)(F_INTERRUPTS * RC5_BIT_TIME + 0.5)
88 #define RC6_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * RC6_START_BIT_PULSE_TIME + 0.5)
89 #define RC6_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RC6_START_BIT_PAUSE_TIME + 0.5)
90 #define RC6_TOGGLE_BIT_LEN (uint8_t)(F_INTERRUPTS * RC6_TOGGLE_BIT_TIME + 0.5)
91 #define RC6_BIT_LEN (uint8_t)(F_INTERRUPTS * RC6_BIT_TIME + 0.5)
93 #define DENON_PULSE_LEN (uint8_t)(F_INTERRUPTS * DENON_PULSE_TIME + 0.5)
94 #define DENON_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * DENON_1_PAUSE_TIME + 0.5)
95 #define DENON_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * DENON_0_PAUSE_TIME + 0.5)
96 #define DENON_REPETITION_LEN (uint16_t)(F_INTERRUPTS * DENON_REPETITION_TIME + 0.5) // use uint16_t!
98 #define RECS80EXT_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PULSE_TIME + 0.5)
99 #define RECS80EXT_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PAUSE_TIME + 0.5)
100 #define RECS80EXT_PULSE_LEN (uint8_t)(F_INTERRUPTS * RECS80EXT_PULSE_TIME + 0.5)
101 #define RECS80EXT_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RECS80EXT_1_PAUSE_TIME + 0.5)
102 #define RECS80EXT_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RECS80EXT_0_PAUSE_TIME + 0.5)
104 #define NUBERT_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * NUBERT_START_BIT_PULSE_TIME + 0.5)
105 #define NUBERT_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NUBERT_START_BIT_PAUSE_TIME + 0.5)
106 #define NUBERT_1_PULSE_LEN (uint8_t)(F_INTERRUPTS * NUBERT_1_PULSE_TIME + 0.5)
107 #define NUBERT_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NUBERT_1_PAUSE_TIME + 0.5)
108 #define NUBERT_0_PULSE_LEN (uint8_t)(F_INTERRUPTS * NUBERT_0_PULSE_TIME + 0.5)
109 #define NUBERT_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NUBERT_0_PAUSE_TIME + 0.5)
110 #define NUBERT_REPETITION_LEN (uint16_t)(F_INTERRUPTS * NUBERT_REPETITION_TIME + 0.5) // use uint16_t!
112 #define BANG_OLUFSEN_START_BIT1_PULSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT1_PULSE_TIME + 0.5)
113 #define BANG_OLUFSEN_START_BIT1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT1_PAUSE_TIME + 0.5)
114 #define BANG_OLUFSEN_START_BIT2_PULSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT2_PULSE_TIME + 0.5)
115 #define BANG_OLUFSEN_START_BIT2_PAUSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT2_PAUSE_TIME + 0.5)
116 #define BANG_OLUFSEN_START_BIT3_PULSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT3_PULSE_TIME + 0.5)
117 #define BANG_OLUFSEN_START_BIT3_PAUSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT3_PAUSE_TIME + 0.5)
118 #define BANG_OLUFSEN_PULSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_PULSE_TIME + 0.5)
119 #define BANG_OLUFSEN_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_1_PAUSE_TIME + 0.5)
120 #define BANG_OLUFSEN_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_0_PAUSE_TIME + 0.5)
121 #define BANG_OLUFSEN_R_PAUSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_R_PAUSE_TIME + 0.5)
122 #define BANG_OLUFSEN_TRAILER_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_TRAILER_BIT_PAUSE_TIME + 0.5)
124 #define IRSND_FREQ_32_KHZ (uint8_t) ((F_CPU / 32000 / 2) - 1)
125 #define IRSND_FREQ_36_KHZ (uint8_t) ((F_CPU / 36000 / 2) - 1)
126 #define IRSND_FREQ_38_KHZ (uint8_t) ((F_CPU / 38000 / 2) - 1)
127 #define IRSND_FREQ_40_KHZ (uint8_t) ((F_CPU / 40000 / 2) - 1)
128 #define IRSND_FREQ_56_KHZ (uint8_t) ((F_CPU / 56000 / 2) - 1)
129 #define IRSND_FREQ_455_KHZ (uint8_t) ((F_CPU / 455000 / 2) - 1)
131 static volatile uint8_t irsnd_busy
;
132 static volatile uint8_t irsnd_protocol
;
133 static volatile uint8_t irsnd_buffer
[5];
134 static volatile uint8_t irsnd_is_on
= FALSE
;
136 /*---------------------------------------------------------------------------------------------------------------------------------------------------
138 * @details Switches PWM on with a narrow spike on all 3 channels -> leds glowing
139 *---------------------------------------------------------------------------------------------------------------------------------------------------
147 #if defined (__AVR_ATmega32__)
148 TCCR2
|= (1<<COM20
)|(1<<WGM21
); // = 0x42: toggle OC2A on compare match, clear Timer 2 at compare match OCR2A
150 TCCR2A
|= (1<<COM2A0
)|(1<<WGM21
); // = 0x42: toggle OC2A on compare match, clear Timer 2 at compare match OCR2A
157 /*---------------------------------------------------------------------------------------------------------------------------------------------------
159 * @details Switches PWM off
160 *---------------------------------------------------------------------------------------------------------------------------------------------------
168 #if defined (__AVR_ATmega32__)
169 TCCR2
&= ~(1<<COM20
); // normal port operation, OC2A disconnected.
171 TCCR2A
&= ~(1<<COM2A0
); // normal port operation, OC2A disconnected.
173 IRSND_PORT
&= ~(1<<IRSND_BIT
); // set IRSND_BIT to low
179 /*---------------------------------------------------------------------------------------------------------------------------------------------------
181 * @details sets pwm frequency
182 *---------------------------------------------------------------------------------------------------------------------------------------------------
185 irsnd_set_freq (uint8_t freq
)
188 #if defined (__AVR_ATmega32__)
196 /*---------------------------------------------------------------------------------------------------------------------------------------------------
198 * @details Configures 0CR0A, 0CR0B and 0CR2B as PWM channels
199 *---------------------------------------------------------------------------------------------------------------------------------------------------
205 IRSND_PORT
&= ~(1<<IRSND_BIT
); // set IRSND_BIT to low
206 IRSND_DDR
|= (1<<IRSND_BIT
); // set IRSND_BIT to output
208 #if defined (__AVR_ATmega32__)
209 TCCR2
= (1<<WGM21
); // CTC mode
210 TCCR2
|= (1<<CS20
); // 0x01, start Timer 2, no prescaling
212 TCCR2A
= (1<<WGM21
); // CTC mode
213 TCCR2B
|= (1<<CS20
); // 0x01, start Timer 2, no prescaling
216 irsnd_set_freq (IRSND_FREQ_36_KHZ
); // default frequency
227 bitsrevervse (uint16_t x
, uint8_t len
)
246 irsnd_send_data (IRMP_DATA
* irmp_data_p
)
248 #if IRSND_SUPPORT_RECS80_PROTOCOL == 1
249 static uint8_t toggle_bit_recs80
;
251 #if IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1
252 static uint8_t toggle_bit_recs80ext
;
254 #if IRSND_SUPPORT_RC5_PROTOCOL == 1
255 static uint8_t toggle_bit_rc5
;
265 irsnd_protocol
= irmp_data_p
->protocol
;
267 switch (irsnd_protocol
)
269 #if IRSND_SUPPORT_SIRCS_PROTOCOL == 1
270 case IRMP_SIRCS_PROTOCOL
:
272 command
= bitsrevervse (irmp_data_p
->command
, SIRCS_MINIMUM_DATA_LEN
);
274 irsnd_buffer
[0] = (command
& 0x0FF0) >> 4; // CCCCCCCC
275 irsnd_buffer
[1] = (command
& 0x000F) << 4; // CCCC0000
280 #if IRSND_SUPPORT_NEC_PROTOCOL == 1
281 case IRMP_NEC_PROTOCOL
:
282 case IRMP_APPLE_PROTOCOL
:
284 address
= bitsrevervse (irmp_data_p
->address
, NEC_ADDRESS_LEN
);
285 command
= bitsrevervse (irmp_data_p
->command
, NEC_COMMAND_LEN
);
287 irsnd_buffer
[0] = (address
& 0xFF00) >> 8; // AAAAAAAA
288 irsnd_buffer
[1] = (address
& 0x00FF); // AAAAAAAA
289 irsnd_buffer
[2] = (command
& 0xFF00) >> 8; // CCCCCCCC
291 if (irsnd_protocol
== IRMP_APPLE_PROTOCOL
)
293 irsnd_protocol
= IRMP_NEC_PROTOCOL
; // APPLE protocol is NEC with fix bitmask instead of inverted command
294 irsnd_buffer
[3] = 0x8B; // 10001011
298 irsnd_buffer
[3] = ~((command
& 0xFF00) >> 8); // cccccccc
305 #if IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1
306 case IRMP_SAMSUNG_PROTOCOL
:
308 address
= bitsrevervse (irmp_data_p
->address
, SAMSUNG_ADDRESS_LEN
);
309 command
= bitsrevervse (irmp_data_p
->command
, SAMSUNG_COMMAND_LEN
);
311 irsnd_buffer
[0] = (address
& 0xFF00) >> 8; // AAAAAAAA
312 irsnd_buffer
[1] = (address
& 0x00FF); // AAAAAAAA
313 irsnd_buffer
[2] = (command
& 0x00F0) | ((command
& 0xF000) >> 12); // IIIICCCC
314 irsnd_buffer
[3] = ((command
& 0x0F00) >> 4) | ((~(command
& 0xF000) >> 12) & 0x0F); // CCCCcccc
315 irsnd_buffer
[4] = (~(command
& 0x0F00) >> 4) & 0xF0; // cccc0000
319 case IRMP_SAMSUNG32_PROTOCOL
:
321 address
= bitsrevervse (irmp_data_p
->address
, SAMSUNG_ADDRESS_LEN
);
322 command
= bitsrevervse (irmp_data_p
->command
, SAMSUNG32_COMMAND_LEN
);
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
& 0x00FF); // CCCCCCCC
332 #if IRSND_SUPPORT_MATSUSHITA_PROTOCOL == 1
333 case IRMP_MATSUSHITA_PROTOCOL
:
335 address
= bitsrevervse (irmp_data_p
->address
, MATSUSHITA_ADDRESS_LEN
);
336 command
= bitsrevervse (irmp_data_p
->command
, MATSUSHITA_COMMAND_LEN
);
338 irsnd_buffer
[0] = (command
& 0x0FF0) >> 4; // CCCCCCCC
339 irsnd_buffer
[1] = ((command
& 0x000F) << 4) | ((address
& 0x0F00) >> 8); // CCCCAAAA
340 irsnd_buffer
[2] = (address
& 0x00FF); // AAAAAAAA
345 #if IRSND_SUPPORT_RECS80_PROTOCOL == 1
346 case IRMP_RECS80_PROTOCOL
:
348 toggle_bit_recs80
= toggle_bit_recs80
? 0x00 : 0x40;
350 irsnd_buffer
[0] = 0x80 | toggle_bit_recs80
| ((irmp_data_p
->address
& 0x0007) << 3) |
351 ((irmp_data_p
->command
& 0x0038) >> 3); // STAAACCC
352 irsnd_buffer
[1] = (irmp_data_p
->command
& 0x07) << 5; // CCC00000
357 #if IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1
358 case IRMP_RECS80EXT_PROTOCOL
:
360 toggle_bit_recs80ext
= toggle_bit_recs80ext
? 0x00 : 0x40;
362 irsnd_buffer
[0] = 0x80 | toggle_bit_recs80ext
| ((irmp_data_p
->address
& 0x000F) << 2) |
363 ((irmp_data_p
->command
& 0x0030) >> 4); // STAAAACC
364 irsnd_buffer
[1] = (irmp_data_p
->command
& 0x0F) << 4; // CCCC0000
369 #if IRSND_SUPPORT_RC5_PROTOCOL == 1
370 case IRMP_RC5_PROTOCOL
:
372 toggle_bit_rc5
= toggle_bit_rc5
? 0x00 : 0x40;
374 irsnd_buffer
[0] = ((irmp_data_p
->command
& 0x40) ? 0x00 : 0x80) | toggle_bit_rc5
|
375 ((irmp_data_p
->address
& 0x001F) << 1) | ((irmp_data_p
->command
& 0x20) >> 5); // CTAAAAAC
376 irsnd_buffer
[1] = (irmp_data_p
->command
& 0x1F) << 3; // CCCCC000
381 #if IRSND_SUPPORT_DENON_PROTOCOL == 1
382 case IRMP_DENON_PROTOCOL
:
384 irsnd_buffer
[0] = ((irmp_data_p
->address
& 0x1F) << 3) | ((irmp_data_p
->command
& 0x0380) >> 7); // AAAAACCC
385 irsnd_buffer
[1] = (irmp_data_p
->command
& 0x7F) << 1; // CCCCCCC0
386 irsnd_buffer
[2] = ((irmp_data_p
->address
& 0x1F) << 3) | (((~irmp_data_p
->command
) & 0x0380) >> 7); // AAAAACCC
387 irsnd_buffer
[3] = (~(irmp_data_p
->command
) & 0x7F) << 1; // CCCCCCC0
392 #if IRSND_SUPPORT_NUBERT_PROTOCOL == 1
393 case IRMP_NUBERT_PROTOCOL
:
395 irsnd_buffer
[0] = irmp_data_p
->command
>> 2; // CCCCCCCC
396 irsnd_buffer
[1] = (irmp_data_p
->command
& 0x0003) << 6; // CC000000
401 #if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1
402 case IRMP_BANG_OLUFSEN_PROTOCOL
:
404 irsnd_buffer
[0] = irmp_data_p
->command
>> 11; // SXSCCCCC
405 irsnd_buffer
[1] = irmp_data_p
->command
>> 3; // CCCCCCCC
406 irsnd_buffer
[2] = (irmp_data_p
->command
& 0x0007) << 5; // CCC00000
420 /*---------------------------------------------------------------------------------------------------------------------------------------------------
422 * @details ISR routine, called 10000 times per second
423 *---------------------------------------------------------------------------------------------------------------------------------------------------
428 static uint8_t current_bit
= 0xFF;
429 static uint8_t pulse_counter
;
430 static uint8_t pause_counter
;
431 static uint8_t startbit_pulse_len
;
432 static uint8_t startbit_pause_len
;
433 static uint8_t pulse_1_len
;
434 static uint8_t pause_1_len
;
435 static uint8_t pulse_0_len
;
436 static uint8_t pause_0_len
;
437 static uint8_t has_stop_bit
;
438 static uint8_t new_frame
= TRUE
;
439 static uint8_t complete_data_len
;
440 static uint8_t n_frames
; // number of repetitions
441 static uint8_t frame_counter
; // repetition counter
442 static uint16_t repetition_pause
; // pause before repetition, uint16_t!
443 static uint16_t repetition_pause_counter
; // pause before repetition, uint16_t!
444 #if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1
445 static uint8_t last_bit_value
;
447 static uint8_t pulse_len
= 0xFF;
448 static uint8_t pause_len
= 0xFF;
452 if (current_bit
== 0xFF && new_frame
) // start of transmission...
454 if (frame_counter
> 0)
456 repetition_pause_counter
++;
458 if (repetition_pause_counter
>= repetition_pause
)
460 repetition_pause_counter
= 0;
462 if (irsnd_protocol
== IRMP_DENON_PROTOCOL
)
465 complete_data_len
= 2 * DENON_COMPLETE_DATA_LEN
+ 1;
488 switch (irsnd_protocol
)
490 #if IRSND_SUPPORT_SIRCS_PROTOCOL == 1
491 case IRMP_SIRCS_PROTOCOL
:
493 startbit_pulse_len
= SIRCS_START_BIT_PULSE_LEN
;
494 startbit_pause_len
= SIRCS_START_BIT_PAUSE_LEN
;
495 pulse_1_len
= SIRCS_1_PULSE_LEN
;
496 pause_1_len
= SIRCS_PAUSE_LEN
;
497 pulse_0_len
= SIRCS_0_PULSE_LEN
;
498 pause_0_len
= SIRCS_PAUSE_LEN
;
499 has_stop_bit
= SIRCS_STOP_BIT
;
500 complete_data_len
= SIRCS_MINIMUM_DATA_LEN
;
501 n_frames
= SIRCS_REPETITION_CNT
;
502 repetition_pause
= SIRCS_REPETITION_LEN
; // 45 ms pause
503 irsnd_set_freq (IRSND_FREQ_40_KHZ
);
507 #if IRSND_SUPPORT_NEC_PROTOCOL == 1
508 case IRMP_NEC_PROTOCOL
:
510 startbit_pulse_len
= NEC_START_BIT_PULSE_LEN
;
511 startbit_pause_len
= NEC_START_BIT_PAUSE_LEN
;
512 pulse_1_len
= NEC_PULSE_LEN
;
513 pause_1_len
= NEC_1_PAUSE_LEN
;
514 pulse_0_len
= NEC_PULSE_LEN
;
515 pause_0_len
= NEC_0_PAUSE_LEN
;
516 has_stop_bit
= NEC_STOP_BIT
;
517 complete_data_len
= NEC_COMPLETE_DATA_LEN
;
519 irsnd_set_freq (IRSND_FREQ_38_KHZ
);
523 #if IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1
524 case IRMP_SAMSUNG_PROTOCOL
:
526 startbit_pulse_len
= SAMSUNG_START_BIT_PULSE_LEN
;
527 startbit_pause_len
= SAMSUNG_START_BIT_PAUSE_LEN
;
528 pulse_1_len
= SAMSUNG_PULSE_LEN
;
529 pause_1_len
= SAMSUNG_1_PAUSE_LEN
;
530 pulse_0_len
= SAMSUNG_PULSE_LEN
;
531 pause_0_len
= SAMSUNG_0_PAUSE_LEN
;
532 has_stop_bit
= SAMSUNG_STOP_BIT
;
533 complete_data_len
= SAMSUNG_COMPLETE_DATA_LEN
;
535 irsnd_set_freq (IRSND_FREQ_38_KHZ
);
539 case IRMP_SAMSUNG32_PROTOCOL
:
541 startbit_pulse_len
= SAMSUNG_START_BIT_PULSE_LEN
;
542 startbit_pause_len
= SAMSUNG_START_BIT_PAUSE_LEN
;
543 pulse_1_len
= SAMSUNG_PULSE_LEN
;
544 pause_1_len
= SAMSUNG_1_PAUSE_LEN
;
545 pulse_0_len
= SAMSUNG_PULSE_LEN
;
546 pause_0_len
= SAMSUNG_0_PAUSE_LEN
;
547 has_stop_bit
= SAMSUNG_STOP_BIT
;
548 complete_data_len
= SAMSUNG32_COMPLETE_DATA_LEN
;
550 irsnd_set_freq (IRSND_FREQ_38_KHZ
);
554 #if IRSND_SUPPORT_MATSUSHITA_PROTOCOL == 1
555 case IRMP_MATSUSHITA_PROTOCOL
:
557 startbit_pulse_len
= MATSUSHITA_START_BIT_PULSE_LEN
;
558 startbit_pause_len
= MATSUSHITA_START_BIT_PAUSE_LEN
;
559 pulse_1_len
= MATSUSHITA_PULSE_LEN
;
560 pause_1_len
= MATSUSHITA_1_PAUSE_LEN
;
561 pulse_0_len
= MATSUSHITA_PULSE_LEN
;
562 pause_0_len
= MATSUSHITA_0_PAUSE_LEN
;
563 has_stop_bit
= MATSUSHITA_STOP_BIT
;
564 complete_data_len
= MATSUSHITA_COMPLETE_DATA_LEN
;
566 irsnd_set_freq (IRSND_FREQ_36_KHZ
);
570 #if IRSND_SUPPORT_RECS80_PROTOCOL == 1
571 case IRMP_RECS80_PROTOCOL
:
573 startbit_pulse_len
= RECS80_START_BIT_PULSE_LEN
;
574 startbit_pause_len
= RECS80_START_BIT_PAUSE_LEN
;
575 pulse_1_len
= RECS80_PULSE_LEN
;
576 pause_1_len
= RECS80_1_PAUSE_LEN
;
577 pulse_0_len
= RECS80_PULSE_LEN
;
578 pause_0_len
= RECS80_0_PAUSE_LEN
;
579 has_stop_bit
= RECS80_STOP_BIT
;
580 complete_data_len
= RECS80_COMPLETE_DATA_LEN
;
582 irsnd_set_freq (IRSND_FREQ_38_KHZ
);
586 #if IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1
587 case IRMP_RECS80EXT_PROTOCOL
:
589 startbit_pulse_len
= RECS80EXT_START_BIT_PULSE_LEN
;
590 startbit_pause_len
= RECS80EXT_START_BIT_PAUSE_LEN
;
591 pulse_1_len
= RECS80EXT_PULSE_LEN
;
592 pause_1_len
= RECS80EXT_1_PAUSE_LEN
;
593 pulse_0_len
= RECS80EXT_PULSE_LEN
;
594 pause_0_len
= RECS80EXT_0_PAUSE_LEN
;
595 has_stop_bit
= RECS80EXT_STOP_BIT
;
596 complete_data_len
= RECS80EXT_COMPLETE_DATA_LEN
;
598 irsnd_set_freq (IRSND_FREQ_38_KHZ
);
602 #if IRSND_SUPPORT_RC5_PROTOCOL == 1
603 case IRMP_RC5_PROTOCOL
:
605 startbit_pulse_len
= RC5_BIT_LEN
;
606 startbit_pause_len
= RC5_BIT_LEN
;
607 pulse_1_len
= RC5_BIT_LEN
;
608 pause_1_len
= RC5_BIT_LEN
;
609 pulse_0_len
= RC5_BIT_LEN
;
610 pause_0_len
= RC5_BIT_LEN
;
611 has_stop_bit
= RC5_STOP_BIT
;
612 complete_data_len
= RC5_COMPLETE_DATA_LEN
;
614 irsnd_set_freq (IRSND_FREQ_36_KHZ
);
618 #if IRSND_SUPPORT_DENON_PROTOCOL == 1
619 case IRMP_DENON_PROTOCOL
:
621 startbit_pulse_len
= 0x00;
622 startbit_pause_len
= 0x00;
623 pulse_1_len
= DENON_PULSE_LEN
;
624 pause_1_len
= DENON_1_PAUSE_LEN
;
625 pulse_0_len
= DENON_PULSE_LEN
;
626 pause_0_len
= DENON_0_PAUSE_LEN
;
627 has_stop_bit
= DENON_STOP_BIT
;
628 complete_data_len
= DENON_COMPLETE_DATA_LEN
;
630 repetition_pause
= DENON_REPETITION_LEN
; // 65 ms pause after 1st frame (15 bits)
631 irsnd_set_freq (IRSND_FREQ_32_KHZ
);
635 #if IRSND_SUPPORT_NUBERT_PROTOCOL == 1
636 case IRMP_NUBERT_PROTOCOL
:
638 startbit_pulse_len
= NUBERT_START_BIT_PULSE_LEN
;
639 startbit_pause_len
= NUBERT_START_BIT_PAUSE_LEN
;
640 pulse_1_len
= NUBERT_1_PULSE_LEN
;
641 pause_1_len
= NUBERT_1_PAUSE_LEN
;
642 pulse_0_len
= NUBERT_0_PULSE_LEN
;
643 pause_0_len
= NUBERT_0_PAUSE_LEN
;
644 has_stop_bit
= NUBERT_STOP_BIT
;
645 complete_data_len
= NUBERT_COMPLETE_DATA_LEN
;
647 repetition_pause
= NUBERT_REPETITION_LEN
; // 35 ms pause
648 irsnd_set_freq (IRSND_FREQ_36_KHZ
);
652 #if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1
653 case IRMP_BANG_OLUFSEN_PROTOCOL
:
655 startbit_pulse_len
= BANG_OLUFSEN_START_BIT1_PULSE_LEN
;
656 startbit_pause_len
= BANG_OLUFSEN_START_BIT1_PAUSE_LEN
;
657 pulse_1_len
= BANG_OLUFSEN_PULSE_LEN
;
658 pause_1_len
= BANG_OLUFSEN_1_PAUSE_LEN
;
659 pulse_0_len
= BANG_OLUFSEN_PULSE_LEN
;
660 pause_0_len
= BANG_OLUFSEN_0_PAUSE_LEN
;
661 has_stop_bit
= BANG_OLUFSEN_STOP_BIT
;
662 complete_data_len
= BANG_OLUFSEN_COMPLETE_DATA_LEN
;
665 irsnd_set_freq (IRSND_FREQ_455_KHZ
);
681 switch (irsnd_protocol
)
683 #if IRSND_SUPPORT_SIRCS_PROTOCOL == 1
684 case IRMP_SIRCS_PROTOCOL
:
686 #if IRSND_SUPPORT_NEC_PROTOCOL == 1
687 case IRMP_NEC_PROTOCOL
:
689 #if IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1
690 case IRMP_SAMSUNG_PROTOCOL
:
691 case IRMP_SAMSUNG32_PROTOCOL
:
693 #if IRSND_SUPPORT_MATSUSHITA_PROTOCOL == 1
694 case IRMP_MATSUSHITA_PROTOCOL
:
696 #if IRSND_SUPPORT_RECS80_PROTOCOL == 1
697 case IRMP_RECS80_PROTOCOL
:
699 #if IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1
700 case IRMP_RECS80EXT_PROTOCOL
:
702 #if IRSND_SUPPORT_DENON_PROTOCOL == 1
703 case IRMP_DENON_PROTOCOL
:
705 #if IRSND_SUPPORT_NUBERT_PROTOCOL == 1
706 case IRMP_NUBERT_PROTOCOL
:
708 #if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1
709 case IRMP_BANG_OLUFSEN_PROTOCOL
:
712 if (pulse_counter
== 0)
714 if (current_bit
== 0xFF) // send start bit
716 pulse_len
= startbit_pulse_len
;
717 pause_len
= startbit_pause_len
;
719 else if (current_bit
< complete_data_len
) // send n'th bit
721 #if IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1
722 if (irsnd_protocol
== IRMP_SAMSUNG_PROTOCOL
)
724 if (current_bit
< SAMSUNG_ADDRESS_LEN
) // send address bits
726 pulse_len
= SAMSUNG_PULSE_LEN
;
727 pause_len
= (irsnd_buffer
[current_bit
/ 8] & (1<<(7-(current_bit
% 8)))) ?
728 SAMSUNG_1_PAUSE_LEN
: SAMSUNG_0_PAUSE_LEN
;
730 else if (current_bit
== SAMSUNG_ADDRESS_LEN
) // send SYNC bit (16th bit)
732 pulse_len
= SAMSUNG_PULSE_LEN
;
733 pause_len
= SAMSUNG_START_BIT_PAUSE_LEN
;
735 else if (current_bit
< SAMSUNG_COMPLETE_DATA_LEN
) // send n'th bit
737 uint8_t cur_bit
= current_bit
- 1; // sync skipped, offset = -1 !
739 pulse_len
= SAMSUNG_PULSE_LEN
;
740 pause_len
= (irsnd_buffer
[cur_bit
/ 8] & (1<<(7-(cur_bit
% 8)))) ?
741 SAMSUNG_1_PAUSE_LEN
: SAMSUNG_0_PAUSE_LEN
;
747 #if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1
748 if (irsnd_protocol
== IRMP_BANG_OLUFSEN_PROTOCOL
)
750 if (current_bit
== 0) // send 2nd start bit
752 pulse_len
= BANG_OLUFSEN_START_BIT2_PULSE_LEN
;
753 pause_len
= BANG_OLUFSEN_START_BIT2_PAUSE_LEN
;
755 else if (current_bit
== 1) // send 3rd start bit
757 pulse_len
= BANG_OLUFSEN_START_BIT3_PULSE_LEN
;
758 pause_len
= BANG_OLUFSEN_START_BIT3_PAUSE_LEN
;
760 else if (current_bit
== 2) // send 4th start bit
762 pulse_len
= BANG_OLUFSEN_START_BIT2_PULSE_LEN
;
763 pause_len
= BANG_OLUFSEN_START_BIT2_PAUSE_LEN
;
765 else if (current_bit
== 19) // send trailer bit
767 pulse_len
= BANG_OLUFSEN_PULSE_LEN
;
768 pause_len
= BANG_OLUFSEN_TRAILER_BIT_PAUSE_LEN
;
770 else if (current_bit
< BANG_OLUFSEN_COMPLETE_DATA_LEN
) // send n'th bit
772 uint8_t cur_bit_value
= (irsnd_buffer
[current_bit
/ 8] & (1<<(7-(current_bit
% 8)))) ? 1 : 0;
773 pulse_len
= BANG_OLUFSEN_PULSE_LEN
;
775 if (cur_bit_value
== last_bit_value
)
777 pause_len
= BANG_OLUFSEN_R_PAUSE_LEN
;
781 pause_len
= cur_bit_value
? BANG_OLUFSEN_1_PAUSE_LEN
: BANG_OLUFSEN_0_PAUSE_LEN
;
782 last_bit_value
= cur_bit_value
;
788 if (irsnd_buffer
[current_bit
/ 8] & (1<<(7-(current_bit
% 8))))
790 pulse_len
= pulse_1_len
;
791 pause_len
= pause_1_len
;
795 pulse_len
= pulse_0_len
;
796 pause_len
= pause_0_len
;
799 else if (has_stop_bit
) // send stop bit
801 pulse_len
= pulse_0_len
;
803 if (frame_counter
< n_frames
)
805 pause_len
= pause_0_len
;
809 pause_len
= 255; // last frame: pause of 255
814 if (pulse_counter
< pulse_len
)
816 if (pulse_counter
== 0)
822 else if (pause_counter
< pause_len
)
824 if (pause_counter
== 0)
834 if (current_bit
>= complete_data_len
+ has_stop_bit
)
839 if (frame_counter
== n_frames
)
852 #if IRSND_SUPPORT_RC5_PROTOCOL == 1
853 case IRMP_RC5_PROTOCOL
:
856 uint8_t next_bit
= FALSE
;
858 if (current_bit
== 0xFF) // 1 start bit
862 else // send n'th bit
864 first_pulse
= (irsnd_buffer
[current_bit
/ 8] & (1<<(7-(current_bit
% 8)))) ? FALSE
: TRUE
;
869 if (pulse_counter
< RC5_BIT_LEN
)
871 if (pulse_counter
== 0)
877 else if (pause_counter
< RC5_BIT_LEN
)
879 if (pause_counter
== 0)
892 if (pause_counter
< RC5_BIT_LEN
)
894 if (pause_counter
== 0)
900 else if (pulse_counter
< RC5_BIT_LEN
)
902 if (pulse_counter
== 0)
918 if (current_bit
>= RC5_COMPLETE_DATA_LEN
)
931 #endif // IRSND_SUPPORT_RC5_PROTOCOL
957 // main function - for unix/linux + windows only!
959 // Compile it under linux with:
960 // cc irsnd.c -o irsnd
962 // usage: ./irsnd protocol hex-address hex-command >filename
965 main (int argc
, char ** argv
)
977 fprintf (stderr
, "usage: %s protocol hex-address hex-command > filename\n", argv
[0]);
981 if (sscanf (argv
[1], "%d", &protocol
) == 1 &&
982 sscanf (argv
[2], "%x", &address
) == 1 &&
983 sscanf (argv
[3], "%x", &command
) == 1)
985 irmp_data
.protocol
= protocol
;
986 irmp_data
.address
= address
;
987 irmp_data
.command
= command
;
991 for (cnt
= 0; cnt
< repeat
; cnt
++)
993 (void) irsnd_send_data (&irmp_data
);
995 for (idx
= 0; idx
< 3000; idx
++)
1005 fprintf (stderr
, "%s: wrong arguments\n", argv
[0]);