]> cloudbase.mooo.com Git - irmp.git/blob - irsnd.c
corrected modulation frequency for denon protocol in irsnd.c, corrected #if for toggl...
[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.29 2011/01/18 13:02:15 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 #include <stdlib.h>
30 #include <string.h>
31
32 #define F_CPU 8000000L
33 typedef unsigned char uint8_t;
34 typedef unsigned short uint16_t;
35 #define DEBUG
36
37 #else
38
39 #ifdef CODEVISION
40 #define COM2A0 6
41 #define WGM21 1
42 #define CS20 0
43 #else
44 #include <inttypes.h>
45 #include <avr/io.h>
46 #include <util/delay.h>
47 #include <avr/pgmspace.h>
48 #endif // CODEVISION
49
50 #endif // WIN32
51 #endif // unix
52
53 #include "irmp.h"
54 #include "irsndconfig.h"
55 #include "irsnd.h"
56
57 #if IRSND_SUPPORT_NIKON_PROTOCOL == 1
58 typedef uint16_t IRSND_PAUSE_LEN;
59 #else
60 typedef uint8_t IRSND_PAUSE_LEN;
61 #endif
62
63 #define SIRCS_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * SIRCS_START_BIT_PULSE_TIME + 0.5)
64 #define SIRCS_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * SIRCS_START_BIT_PAUSE_TIME + 0.5)
65 #define SIRCS_1_PULSE_LEN (uint8_t)(F_INTERRUPTS * SIRCS_1_PULSE_TIME + 0.5)
66 #define SIRCS_0_PULSE_LEN (uint8_t)(F_INTERRUPTS * SIRCS_0_PULSE_TIME + 0.5)
67 #define SIRCS_PAUSE_LEN (uint8_t)(F_INTERRUPTS * SIRCS_PAUSE_TIME + 0.5)
68 #define SIRCS_AUTO_REPETITION_PAUSE_LEN (uint16_t)(F_INTERRUPTS * SIRCS_AUTO_REPETITION_PAUSE_TIME + 0.5) // use uint16_t!
69 #define SIRCS_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * SIRCS_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
70
71 #define NEC_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * NEC_START_BIT_PULSE_TIME + 0.5)
72 #define NEC_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NEC_START_BIT_PAUSE_TIME + 0.5)
73 #define NEC_REPEAT_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NEC_REPEAT_START_BIT_PAUSE_TIME + 0.5)
74 #define NEC_PULSE_LEN (uint8_t)(F_INTERRUPTS * NEC_PULSE_TIME + 0.5)
75 #define NEC_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NEC_1_PAUSE_TIME + 0.5)
76 #define NEC_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NEC_0_PAUSE_TIME + 0.5)
77 #define NEC_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * NEC_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
78
79 #define SAMSUNG_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PULSE_TIME + 0.5)
80 #define SAMSUNG_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PAUSE_TIME + 0.5)
81 #define SAMSUNG_PULSE_LEN (uint8_t)(F_INTERRUPTS * SAMSUNG_PULSE_TIME + 0.5)
82 #define SAMSUNG_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * SAMSUNG_1_PAUSE_TIME + 0.5)
83 #define SAMSUNG_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * SAMSUNG_0_PAUSE_TIME + 0.5)
84 #define SAMSUNG_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * SAMSUNG_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
85
86 #define SAMSUNG32_AUTO_REPETITION_PAUSE_LEN (uint16_t)(F_INTERRUPTS * SAMSUNG32_AUTO_REPETITION_PAUSE_TIME + 0.5) // use uint16_t!
87 #define SAMSUNG32_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * SAMSUNG32_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
88
89 #define MATSUSHITA_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PULSE_TIME + 0.5)
90 #define MATSUSHITA_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PAUSE_TIME + 0.5)
91 #define MATSUSHITA_PULSE_LEN (uint8_t)(F_INTERRUPTS * MATSUSHITA_PULSE_TIME + 0.5)
92 #define MATSUSHITA_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * MATSUSHITA_1_PAUSE_TIME + 0.5)
93 #define MATSUSHITA_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * MATSUSHITA_0_PAUSE_TIME + 0.5)
94 #define MATSUSHITA_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * MATSUSHITA_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
95
96 #define KASEIKYO_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PULSE_TIME + 0.5)
97 #define KASEIKYO_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PAUSE_TIME + 0.5)
98 #define KASEIKYO_PULSE_LEN (uint8_t)(F_INTERRUPTS * KASEIKYO_PULSE_TIME + 0.5)
99 #define KASEIKYO_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * KASEIKYO_1_PAUSE_TIME + 0.5)
100 #define KASEIKYO_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * KASEIKYO_0_PAUSE_TIME + 0.5)
101 #define KASEIKYO_AUTO_REPETITION_PAUSE_LEN (uint16_t)(F_INTERRUPTS * KASEIKYO_AUTO_REPETITION_PAUSE_TIME + 0.5) // use uint16_t!
102 #define KASEIKYO_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * KASEIKYO_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
103
104 #define RECS80_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * RECS80_START_BIT_PULSE_TIME + 0.5)
105 #define RECS80_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RECS80_START_BIT_PAUSE_TIME + 0.5)
106 #define RECS80_PULSE_LEN (uint8_t)(F_INTERRUPTS * RECS80_PULSE_TIME + 0.5)
107 #define RECS80_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RECS80_1_PAUSE_TIME + 0.5)
108 #define RECS80_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RECS80_0_PAUSE_TIME + 0.5)
109 #define RECS80_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * RECS80_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
110
111 #define RC5_START_BIT_LEN (uint8_t)(F_INTERRUPTS * RC5_BIT_TIME + 0.5)
112 #define RC5_BIT_LEN (uint8_t)(F_INTERRUPTS * RC5_BIT_TIME + 0.5)
113 #define RC5_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * RC5_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
114
115 #define RC6_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * RC6_START_BIT_PULSE_TIME + 0.5)
116 #define RC6_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RC6_START_BIT_PAUSE_TIME + 0.5)
117 #define RC6_TOGGLE_BIT_LEN (uint8_t)(F_INTERRUPTS * RC6_TOGGLE_BIT_TIME + 0.5)
118 #define RC6_BIT_LEN (uint8_t)(F_INTERRUPTS * RC6_BIT_TIME + 0.5)
119 #define RC6_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * RC6_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
120
121 #define DENON_PULSE_LEN (uint8_t)(F_INTERRUPTS * DENON_PULSE_TIME + 0.5)
122 #define DENON_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * DENON_1_PAUSE_TIME + 0.5)
123 #define DENON_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * DENON_0_PAUSE_TIME + 0.5)
124 #define DENON_AUTO_REPETITION_PAUSE_LEN (uint16_t)(F_INTERRUPTS * DENON_AUTO_REPETITION_PAUSE_TIME + 0.5) // use uint16_t!
125 #define DENON_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * DENON_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
126
127 #define RECS80EXT_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PULSE_TIME + 0.5)
128 #define RECS80EXT_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PAUSE_TIME + 0.5)
129 #define RECS80EXT_PULSE_LEN (uint8_t)(F_INTERRUPTS * RECS80EXT_PULSE_TIME + 0.5)
130 #define RECS80EXT_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RECS80EXT_1_PAUSE_TIME + 0.5)
131 #define RECS80EXT_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RECS80EXT_0_PAUSE_TIME + 0.5)
132 #define RECS80EXT_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * RECS80EXT_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
133
134 #define NUBERT_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * NUBERT_START_BIT_PULSE_TIME + 0.5)
135 #define NUBERT_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NUBERT_START_BIT_PAUSE_TIME + 0.5)
136 #define NUBERT_1_PULSE_LEN (uint8_t)(F_INTERRUPTS * NUBERT_1_PULSE_TIME + 0.5)
137 #define NUBERT_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NUBERT_1_PAUSE_TIME + 0.5)
138 #define NUBERT_0_PULSE_LEN (uint8_t)(F_INTERRUPTS * NUBERT_0_PULSE_TIME + 0.5)
139 #define NUBERT_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NUBERT_0_PAUSE_TIME + 0.5)
140 #define NUBERT_AUTO_REPETITION_PAUSE_LEN (uint16_t)(F_INTERRUPTS * NUBERT_AUTO_REPETITION_PAUSE_TIME + 0.5) // use uint16_t!
141 #define NUBERT_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * NUBERT_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
142
143 #define BANG_OLUFSEN_START_BIT1_PULSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT1_PULSE_TIME + 0.5)
144 #define BANG_OLUFSEN_START_BIT1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT1_PAUSE_TIME + 0.5)
145 #define BANG_OLUFSEN_START_BIT2_PULSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT2_PULSE_TIME + 0.5)
146 #define BANG_OLUFSEN_START_BIT2_PAUSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT2_PAUSE_TIME + 0.5)
147 #define BANG_OLUFSEN_START_BIT3_PULSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT3_PULSE_TIME + 0.5)
148 #define BANG_OLUFSEN_START_BIT3_PAUSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT3_PAUSE_TIME + 0.5)
149 #define BANG_OLUFSEN_PULSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_PULSE_TIME + 0.5)
150 #define BANG_OLUFSEN_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_1_PAUSE_TIME + 0.5)
151 #define BANG_OLUFSEN_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_0_PAUSE_TIME + 0.5)
152 #define BANG_OLUFSEN_R_PAUSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_R_PAUSE_TIME + 0.5)
153 #define BANG_OLUFSEN_TRAILER_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_TRAILER_BIT_PAUSE_TIME + 0.5)
154 #define BANG_OLUFSEN_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * BANG_OLUFSEN_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
155
156 #define GRUNDIG_OR_NOKIA_PRE_PAUSE_LEN (uint8_t)(F_INTERRUPTS * GRUNDIG_OR_NOKIA_PRE_PAUSE_TIME + 0.5)
157 #define GRUNDIG_OR_NOKIA_BIT_LEN (uint8_t)(F_INTERRUPTS * GRUNDIG_OR_NOKIA_BIT_TIME + 0.5)
158 #define GRUNDIG_AUTO_REPETITION_PAUSE_LEN (uint16_t)(F_INTERRUPTS * GRUNDIG_AUTO_REPETITION_PAUSE_TIME + 0.5) // use uint16_t!
159 #define NOKIA_AUTO_REPETITION_PAUSE_LEN (uint16_t)(F_INTERRUPTS * NOKIA_AUTO_REPETITION_PAUSE_TIME + 0.5) // use uint16_t!
160 #define GRUNDIG_OR_NOKIA_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * GRUNDIG_OR_NOKIA_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
161
162 #define SIEMENS_START_BIT_LEN (uint8_t)(F_INTERRUPTS * SIEMENS_BIT_TIME + 0.5)
163 #define SIEMENS_BIT_LEN (uint8_t)(F_INTERRUPTS * SIEMENS_BIT_TIME + 0.5)
164 #define SIEMENS_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * SIEMENS_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
165
166 #define IRSND_FREQ_32_KHZ (uint8_t) ((F_CPU / 32000 / 2) - 1)
167 #define IRSND_FREQ_36_KHZ (uint8_t) ((F_CPU / 36000 / 2) - 1)
168 #define IRSND_FREQ_38_KHZ (uint8_t) ((F_CPU / 38000 / 2) - 1)
169 #define IRSND_FREQ_40_KHZ (uint8_t) ((F_CPU / 40000 / 2) - 1)
170 #define IRSND_FREQ_56_KHZ (uint8_t) ((F_CPU / 56000 / 2) - 1)
171 #define IRSND_FREQ_455_KHZ (uint8_t) ((F_CPU / 455000 / 2) - 1)
172
173 #define FDC_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * FDC_START_BIT_PULSE_TIME + 0.5)
174 #define FDC_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * FDC_START_BIT_PAUSE_TIME + 0.5)
175 #define FDC_PULSE_LEN (uint8_t)(F_INTERRUPTS * FDC_PULSE_TIME + 0.5)
176 #define FDC_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * FDC_1_PAUSE_TIME + 0.5)
177 #define FDC_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * FDC_0_PAUSE_TIME + 0.5)
178 #define FDC_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * FDC_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
179
180 #define RCCAR_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * RCCAR_START_BIT_PULSE_TIME + 0.5)
181 #define RCCAR_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RCCAR_START_BIT_PAUSE_TIME + 0.5)
182 #define RCCAR_PULSE_LEN (uint8_t)(F_INTERRUPTS * RCCAR_PULSE_TIME + 0.5)
183 #define RCCAR_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RCCAR_1_PAUSE_TIME + 0.5)
184 #define RCCAR_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RCCAR_0_PAUSE_TIME + 0.5)
185 #define RCCAR_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * RCCAR_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
186
187 #define JVC_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * JVC_START_BIT_PULSE_TIME + 0.5)
188 #define JVC_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * JVC_START_BIT_PAUSE_TIME + 0.5)
189 #define JVC_REPEAT_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * JVC_REPEAT_START_BIT_PAUSE_TIME + 0.5)
190 #define JVC_PULSE_LEN (uint8_t)(F_INTERRUPTS * JVC_PULSE_TIME + 0.5)
191 #define JVC_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * JVC_1_PAUSE_TIME + 0.5)
192 #define JVC_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * JVC_0_PAUSE_TIME + 0.5)
193 #define JVC_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * JVC_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
194
195 #define NIKON_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * NIKON_START_BIT_PULSE_TIME + 0.5)
196 #define NIKON_START_BIT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * NIKON_START_BIT_PAUSE_TIME + 0.5)
197 #define NIKON_REPEAT_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NIKON_REPEAT_START_BIT_PAUSE_TIME + 0.5)
198 #define NIKON_PULSE_LEN (uint8_t)(F_INTERRUPTS * NIKON_PULSE_TIME + 0.5)
199 #define NIKON_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NIKON_1_PAUSE_TIME + 0.5)
200 #define NIKON_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NIKON_0_PAUSE_TIME + 0.5)
201 #define NIKON_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * NIKON_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
202
203 static volatile uint8_t irsnd_busy;
204 static volatile uint8_t irsnd_protocol;
205 static volatile uint8_t irsnd_buffer[6];
206 static volatile uint8_t irsnd_repeat;
207 static volatile uint8_t irsnd_is_on = FALSE;
208
209 /*---------------------------------------------------------------------------------------------------------------------------------------------------
210 * Switch PWM on
211 * @details Switches PWM on with a narrow spike on all 3 channels -> leds glowing
212 *---------------------------------------------------------------------------------------------------------------------------------------------------
213 */
214 static void
215 irsnd_on (void)
216 {
217 if (! irsnd_is_on)
218 {
219 #ifndef DEBUG
220 #if defined (__AVR_ATmega32__)
221 TCCR2 |= (1<<COM20)|(1<<WGM21); // = 0x42: toggle OC2A on compare match, clear Timer 2 at compare match OCR2A
222 #else
223 TCCR2A |= (1<<COM2A0)|(1<<WGM21); // = 0x42: toggle OC2A on compare match, clear Timer 2 at compare match OCR2A
224 #endif // __AVR...
225 #endif // DEBUG
226 irsnd_is_on = TRUE;
227 }
228 }
229
230 /*---------------------------------------------------------------------------------------------------------------------------------------------------
231 * Switch PWM off
232 * @details Switches PWM off
233 *---------------------------------------------------------------------------------------------------------------------------------------------------
234 */
235 static void
236 irsnd_off (void)
237 {
238 if (irsnd_is_on)
239 {
240 #ifndef DEBUG
241 #if defined (__AVR_ATmega32__)
242 TCCR2 &= ~(1<<COM20); // normal port operation, OC2A disconnected.
243 #else
244 TCCR2A &= ~(1<<COM2A0); // normal port operation, OC2A disconnected.
245 #endif // __AVR...
246 IRSND_PORT &= ~(1<<IRSND_BIT); // set IRSND_BIT to low
247 #endif // DEBUG
248 irsnd_is_on = FALSE;
249 }
250 }
251
252 /*---------------------------------------------------------------------------------------------------------------------------------------------------
253 * Set PWM frequency
254 * @details sets pwm frequency
255 *---------------------------------------------------------------------------------------------------------------------------------------------------
256 */
257 static void
258 irsnd_set_freq (uint8_t freq)
259 {
260 #ifndef DEBUG
261 #if defined (__AVR_ATmega32__)
262 OCR2 = freq;
263 #else
264 OCR2A = freq;
265 #endif // __AVR...
266 #endif // DEBUG
267 }
268
269 /*---------------------------------------------------------------------------------------------------------------------------------------------------
270 * Initialize the PWM
271 * @details Configures 0CR0A, 0CR0B and 0CR2B as PWM channels
272 *---------------------------------------------------------------------------------------------------------------------------------------------------
273 */
274 void
275 irsnd_init (void)
276 {
277 #ifndef DEBUG
278 IRSND_PORT &= ~(1<<IRSND_BIT); // set IRSND_BIT to low
279 IRSND_DDR |= (1<<IRSND_BIT); // set IRSND_BIT to output
280
281 #if defined (__AVR_ATmega32__)
282 TCCR2 = (1<<WGM21); // CTC mode
283 TCCR2 |= (1<<CS20); // 0x01, start Timer 2, no prescaling
284 #else
285 TCCR2A = (1<<WGM21); // CTC mode
286 TCCR2B |= (1<<CS20); // 0x01, start Timer 2, no prescaling
287 #endif // __AVR...
288
289 irsnd_set_freq (IRSND_FREQ_36_KHZ); // default frequency
290 #endif // DEBUG
291 }
292
293 uint8_t
294 irsnd_is_busy (void)
295 {
296 return irsnd_busy;
297 }
298
299 static uint16_t
300 bitsrevervse (uint16_t x, uint8_t len)
301 {
302 uint16_t xx = 0;
303
304 while(len)
305 {
306 xx <<= 1;
307 if (x & 1)
308 {
309 xx |= 1;
310 }
311 x >>= 1;
312 len--;
313 }
314 return xx;
315 }
316
317
318 #if IRSND_SUPPORT_SIRCS_PROTOCOL == 1
319 static uint8_t sircs_additional_bitlen;
320 #endif // IRSND_SUPPORT_SIRCS_PROTOCOL == 1
321
322 uint8_t
323 irsnd_send_data (IRMP_DATA * irmp_data_p, uint8_t do_wait)
324 {
325 #if IRSND_SUPPORT_RECS80_PROTOCOL == 1
326 static uint8_t toggle_bit_recs80;
327 #endif
328 #if IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1
329 static uint8_t toggle_bit_recs80ext;
330 #endif
331 #if IRSND_SUPPORT_RC5_PROTOCOL == 1
332 static uint8_t toggle_bit_rc5;
333 #endif
334 #if IRSND_SUPPORT_RC6_PROTOCOL == 1 || IRSND_SUPPORT_RC6A_PROTOCOL == 1
335 static uint8_t toggle_bit_rc6;
336 #endif
337 uint16_t address;
338 uint16_t command;
339
340 if (do_wait)
341 {
342 while (irsnd_busy)
343 {
344 // do nothing;
345 }
346 }
347 else if (irsnd_busy)
348 {
349 return (FALSE);
350 }
351
352 irsnd_protocol = irmp_data_p->protocol;
353 irsnd_repeat = irmp_data_p->flags;
354
355 switch (irsnd_protocol)
356 {
357 #if IRSND_SUPPORT_SIRCS_PROTOCOL == 1
358 case IRMP_SIRCS_PROTOCOL:
359 {
360 uint8_t sircs_additional_command_len;
361 uint8_t sircs_additional_address_len;
362
363 sircs_additional_bitlen = (irmp_data_p->address & 0xFF00) >> 8; // additional bitlen
364
365 if (sircs_additional_bitlen > 15 - SIRCS_MINIMUM_DATA_LEN)
366 {
367 sircs_additional_command_len = 15 - SIRCS_MINIMUM_DATA_LEN;
368 sircs_additional_address_len = sircs_additional_bitlen - (15 - SIRCS_MINIMUM_DATA_LEN);
369 }
370 else
371 {
372 sircs_additional_command_len = sircs_additional_bitlen;
373 sircs_additional_address_len = 0;
374 }
375
376 command = bitsrevervse (irmp_data_p->command, 15);
377
378 irsnd_buffer[0] = (command & 0x7F80) >> 7; // CCCCCCCC
379 irsnd_buffer[1] = (command & 0x007F) << 1; // CCCC****
380
381 if (sircs_additional_address_len > 0)
382 {
383 address = bitsrevervse (irmp_data_p->address, 5);
384 irsnd_buffer[1] |= (address & 0x0010) >> 4;
385 irsnd_buffer[2] = (address & 0x000F) << 4;
386 }
387 irsnd_busy = TRUE;
388 break;
389 }
390 #endif
391 #if IRSND_SUPPORT_NEC_PROTOCOL == 1
392 case IRMP_APPLE_PROTOCOL:
393 {
394 command = irmp_data_p->command | (irmp_data_p->address << 8); // store address as ID in upper byte of command
395 address = 0x87EE; // set fixed NEC-lookalike address (customer ID of apple)
396
397 address = bitsrevervse (address, NEC_ADDRESS_LEN);
398 command = bitsrevervse (command, NEC_COMMAND_LEN);
399
400 irsnd_protocol = IRMP_NEC_PROTOCOL; // APPLE protocol is NEC with id instead of inverted command
401
402 irsnd_buffer[0] = (address & 0xFF00) >> 8; // AAAAAAAA
403 irsnd_buffer[1] = (address & 0x00FF); // AAAAAAAA
404 irsnd_buffer[2] = (command & 0xFF00) >> 8; // CCCCCCCC
405 irsnd_buffer[3] = (command & 0x00FF); // CCCCCCCC
406
407 irsnd_busy = TRUE;
408 break;
409 }
410 case IRMP_NEC_PROTOCOL:
411 {
412 address = bitsrevervse (irmp_data_p->address, NEC_ADDRESS_LEN);
413 command = bitsrevervse (irmp_data_p->command, NEC_COMMAND_LEN);
414
415 irsnd_buffer[0] = (address & 0xFF00) >> 8; // AAAAAAAA
416 irsnd_buffer[1] = (address & 0x00FF); // AAAAAAAA
417 irsnd_buffer[2] = (command & 0xFF00) >> 8; // CCCCCCCC
418
419 irsnd_protocol = IRMP_NEC_PROTOCOL; // APPLE protocol is NEC with fix bitmask instead of inverted command
420 irsnd_buffer[3] = 0x8B; // 10001011
421 {
422 irsnd_buffer[3] = ~((command & 0xFF00) >> 8); // cccccccc
423 }
424
425 irsnd_busy = TRUE;
426 break;
427 }
428 #endif
429 #if IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1
430 case IRMP_SAMSUNG_PROTOCOL:
431 {
432 address = bitsrevervse (irmp_data_p->address, SAMSUNG_ADDRESS_LEN);
433 command = bitsrevervse (irmp_data_p->command, SAMSUNG_COMMAND_LEN);
434
435 irsnd_buffer[0] = (address & 0xFF00) >> 8; // AAAAAAAA
436 irsnd_buffer[1] = (address & 0x00FF); // AAAAAAAA
437 irsnd_buffer[2] = (command & 0x00F0) | ((command & 0xF000) >> 12); // IIIICCCC
438 irsnd_buffer[3] = ((command & 0x0F00) >> 4) | ((~(command & 0xF000) >> 12) & 0x0F); // CCCCcccc
439 irsnd_buffer[4] = (~(command & 0x0F00) >> 4) & 0xF0; // cccc0000
440 irsnd_busy = TRUE;
441 break;
442 }
443 case IRMP_SAMSUNG32_PROTOCOL:
444 {
445 address = bitsrevervse (irmp_data_p->address, SAMSUNG_ADDRESS_LEN);
446 command = bitsrevervse (irmp_data_p->command, SAMSUNG32_COMMAND_LEN);
447
448 irsnd_buffer[0] = (address & 0xFF00) >> 8; // AAAAAAAA
449 irsnd_buffer[1] = (address & 0x00FF); // AAAAAAAA
450 irsnd_buffer[2] = (command & 0xFF00) >> 8; // CCCCCCCC
451 irsnd_buffer[3] = (command & 0x00FF); // CCCCCCCC
452 irsnd_busy = TRUE;
453 break;
454 }
455 #endif
456 #if IRSND_SUPPORT_MATSUSHITA_PROTOCOL == 1
457 case IRMP_MATSUSHITA_PROTOCOL:
458 {
459 address = bitsrevervse (irmp_data_p->address, MATSUSHITA_ADDRESS_LEN);
460 command = bitsrevervse (irmp_data_p->command, MATSUSHITA_COMMAND_LEN);
461
462 irsnd_buffer[0] = (command & 0x0FF0) >> 4; // CCCCCCCC
463 irsnd_buffer[1] = ((command & 0x000F) << 4) | ((address & 0x0F00) >> 8); // CCCCAAAA
464 irsnd_buffer[2] = (address & 0x00FF); // AAAAAAAA
465 irsnd_busy = TRUE;
466 break;
467 }
468 #endif
469 #if IRSND_SUPPORT_KASEIKYO_PROTOCOL == 1
470 case IRMP_KASEIKYO_PROTOCOL:
471 {
472 uint8_t xor;
473
474 address = bitsrevervse (irmp_data_p->address, KASEIKYO_ADDRESS_LEN);
475 command = bitsrevervse (irmp_data_p->command, KASEIKYO_COMMAND_LEN + 4);
476
477 xor = ((address & 0x000F) ^ ((address & 0x00F0) >> 4) ^ ((address & 0x0F00) >> 8) ^ ((address & 0xF000) >> 12)) & 0x0F;
478
479 irsnd_buffer[0] = (address & 0xFF00) >> 8; // AAAAAAAA
480 irsnd_buffer[1] = (address & 0x00FF); // AAAAAAAA
481 irsnd_buffer[2] = xor << 4 | (command & 0x000F); // XXXXCCCC
482 irsnd_buffer[3] = 0 | (command & 0xF000) >> 12; // 0000CCCC
483 irsnd_buffer[4] = (command & 0x0FF0) >> 4; // CCCCCCCC
484
485 xor = irsnd_buffer[2] ^ irsnd_buffer[3] ^ irsnd_buffer[4];
486
487 irsnd_buffer[5] = xor;
488 irsnd_busy = TRUE;
489 break;
490 }
491 #endif
492 #if IRSND_SUPPORT_RECS80_PROTOCOL == 1
493 case IRMP_RECS80_PROTOCOL:
494 {
495 toggle_bit_recs80 = toggle_bit_recs80 ? 0x00 : 0x40;
496
497 irsnd_buffer[0] = 0x80 | toggle_bit_recs80 | ((irmp_data_p->address & 0x0007) << 3) |
498 ((irmp_data_p->command & 0x0038) >> 3); // STAAACCC
499 irsnd_buffer[1] = (irmp_data_p->command & 0x07) << 5; // CCC00000
500 irsnd_busy = TRUE;
501 break;
502 }
503 #endif
504 #if IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1
505 case IRMP_RECS80EXT_PROTOCOL:
506 {
507 toggle_bit_recs80ext = toggle_bit_recs80ext ? 0x00 : 0x40;
508
509 irsnd_buffer[0] = 0x80 | toggle_bit_recs80ext | ((irmp_data_p->address & 0x000F) << 2) |
510 ((irmp_data_p->command & 0x0030) >> 4); // STAAAACC
511 irsnd_buffer[1] = (irmp_data_p->command & 0x0F) << 4; // CCCC0000
512 irsnd_busy = TRUE;
513 break;
514 }
515 #endif
516 #if IRSND_SUPPORT_RC5_PROTOCOL == 1
517 case IRMP_RC5_PROTOCOL:
518 {
519 toggle_bit_rc5 = toggle_bit_rc5 ? 0x00 : 0x40;
520
521 irsnd_buffer[0] = ((irmp_data_p->command & 0x40) ? 0x00 : 0x80) | toggle_bit_rc5 |
522 ((irmp_data_p->address & 0x001F) << 1) | ((irmp_data_p->command & 0x20) >> 5); // CTAAAAAC
523 irsnd_buffer[1] = (irmp_data_p->command & 0x1F) << 3; // CCCCC000
524 irsnd_busy = TRUE;
525 break;
526 }
527 #endif
528 #if IRSND_SUPPORT_RC6_PROTOCOL == 1
529 case IRMP_RC6_PROTOCOL:
530 {
531 toggle_bit_rc6 = toggle_bit_rc6 ? 0x00 : 0x08;
532
533 irsnd_buffer[0] = 0x80 | toggle_bit_rc6 | ((irmp_data_p->address & 0x00E0) >> 5); // 1MMMTAAA, MMM = 000
534 irsnd_buffer[1] = ((irmp_data_p->address & 0x001F) << 3) | ((irmp_data_p->command & 0xE0) >> 5); // AAAAACCC
535 irsnd_buffer[2] = (irmp_data_p->command & 0x1F) << 3; // CCCCC
536 irsnd_busy = TRUE;
537 break;
538 }
539 #endif
540 #if IRSND_SUPPORT_RC6A_PROTOCOL == 1
541 case IRMP_RC6A_PROTOCOL:
542 {
543 toggle_bit_rc6 = toggle_bit_rc6 ? 0x00 : 0x08;
544
545 irsnd_buffer[0] = 0x80 | 0x60 | ((irmp_data_p->address & 0x3000) >> 12); // 1MMMT0AA, MMM = 110
546 irsnd_buffer[1] = ((irmp_data_p->address & 0x0FFF) >> 4) ; // AAAAAAAA
547 irsnd_buffer[2] = ((irmp_data_p->address & 0x000F) << 4) | ((irmp_data_p->command & 0xF000) >> 12) | toggle_bit_rc6; // AAAACCCC
548 irsnd_buffer[3] = (irmp_data_p->command & 0x0FF0) >> 4; // CCCCCCCC
549 irsnd_buffer[4] = (irmp_data_p->command & 0x000F) << 4; // CCCC
550 irsnd_busy = TRUE;
551 break;
552 }
553 #endif
554 #if IRSND_SUPPORT_DENON_PROTOCOL == 1
555 case IRMP_DENON_PROTOCOL:
556 {
557 irsnd_buffer[0] = ((irmp_data_p->address & 0x1F) << 3) | ((irmp_data_p->command & 0x0380) >> 7); // AAAAACCC (1st frame)
558 irsnd_buffer[1] = (irmp_data_p->command & 0x7F) << 1; // CCCCCCC
559 irsnd_buffer[2] = ((irmp_data_p->address & 0x1F) << 3) | (((~irmp_data_p->command) & 0x0380) >> 7); // AAAAACCC (2nd frame)
560 irsnd_buffer[3] = (~(irmp_data_p->command) & 0x7F) << 1; // CCCCCCC
561 irsnd_busy = TRUE;
562 break;
563 }
564 #endif
565 #if IRSND_SUPPORT_NUBERT_PROTOCOL == 1
566 case IRMP_NUBERT_PROTOCOL:
567 {
568 irsnd_buffer[0] = irmp_data_p->command >> 2; // CCCCCCCC
569 irsnd_buffer[1] = (irmp_data_p->command & 0x0003) << 6; // CC000000
570 irsnd_busy = TRUE;
571 break;
572 }
573 #endif
574 #if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1
575 case IRMP_BANG_OLUFSEN_PROTOCOL:
576 {
577 irsnd_buffer[0] = irmp_data_p->command >> 11; // SXSCCCCC
578 irsnd_buffer[1] = irmp_data_p->command >> 3; // CCCCCCCC
579 irsnd_buffer[2] = (irmp_data_p->command & 0x0007) << 5; // CCC00000
580 irsnd_busy = TRUE;
581 break;
582 }
583 #endif
584 #if IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1
585 case IRMP_GRUNDIG_PROTOCOL:
586 {
587 command = bitsrevervse (irmp_data_p->command, GRUNDIG_COMMAND_LEN);
588
589 irsnd_buffer[0] = 0xFF; // S1111111 (1st frame)
590 irsnd_buffer[1] = 0xC0; // 11
591 irsnd_buffer[2] = 0x80 | (command >> 2); // SCCCCCCC (2nd frame)
592 irsnd_buffer[3] = (command << 6) & 0xC0; // CC
593
594 irsnd_busy = TRUE;
595 break;
596 }
597 #endif
598 #if IRSND_SUPPORT_NOKIA_PROTOCOL == 1
599 case IRMP_NOKIA_PROTOCOL:
600 {
601 address = bitsrevervse (irmp_data_p->address, NOKIA_ADDRESS_LEN);
602 command = bitsrevervse (irmp_data_p->command, NOKIA_COMMAND_LEN);
603
604 irsnd_buffer[0] = 0xBF; // S0111111 (1st + 3rd frame)
605 irsnd_buffer[1] = 0xFF; // 11111111
606 irsnd_buffer[2] = 0x80; // 1
607 irsnd_buffer[3] = 0x80 | command >> 1; // SCCCCCCC (2nd frame)
608 irsnd_buffer[4] = (command << 7) | (address >> 1); // CAAAAAAA
609 irsnd_buffer[5] = (address << 7); // A
610
611 irsnd_busy = TRUE;
612 break;
613 }
614 #endif
615 #if IRSND_SUPPORT_SIEMENS_PROTOCOL == 1
616 case IRMP_SIEMENS_PROTOCOL:
617 {
618 irsnd_buffer[0] = ((irmp_data_p->address & 0x0FFF) >> 5); // SAAAAAAA
619 irsnd_buffer[1] = ((irmp_data_p->address & 0x1F) << 3) | ((irmp_data_p->command & 0x7F) >> 5); // AAAAA0CC
620 irsnd_buffer[2] = (irmp_data_p->command << 3) | ((~irmp_data_p->command & 0x01) << 2); // CCCCCc
621
622 irsnd_busy = TRUE;
623 break;
624 }
625 #endif
626 #if IRSND_SUPPORT_FDC_PROTOCOL == 1
627 case IRMP_FDC_PROTOCOL:
628 {
629 address = bitsrevervse (irmp_data_p->address, FDC_ADDRESS_LEN);
630 command = bitsrevervse (irmp_data_p->command, FDC_COMMAND_LEN);
631
632 irsnd_buffer[0] = (address & 0xFF); // AAAAAAAA
633 irsnd_buffer[1] = 0; // 00000000
634 irsnd_buffer[2] = 0; // 0000RRRR
635 irsnd_buffer[3] = (command & 0xFF); // CCCCCCCC
636 irsnd_buffer[4] = ~(command & 0xFF); // cccccccc
637 irsnd_busy = TRUE;
638 break;
639 }
640 #endif
641 #if IRSND_SUPPORT_RCCAR_PROTOCOL == 1
642 case IRMP_RCCAR_PROTOCOL:
643 {
644 address = bitsrevervse (irmp_data_p->address, 2); // A0 A1
645 command = bitsrevervse (irmp_data_p->command, RCCAR_COMMAND_LEN - 2); // D0 D1 D2 D3 D4 D5 D6 D7 C0 C1 V
646
647 irsnd_buffer[0] = ((command & 0x06) << 5) | ((address & 0x0003) << 4) | ((command & 0x0780) >> 7); // C0 C1 A0 A1 D0 D1 D2 D3
648 irsnd_buffer[1] = ((command & 0x78) << 1) | ((command & 0x0001) << 3); // D4 D5 D6 D7 V 0 0 0
649
650 irsnd_busy = TRUE;
651 break;
652 }
653 #endif
654 #if IRSND_SUPPORT_JVC_PROTOCOL == 1
655 case IRMP_JVC_PROTOCOL:
656 {
657 address = bitsrevervse (irmp_data_p->address, JVC_ADDRESS_LEN);
658 command = bitsrevervse (irmp_data_p->command, JVC_COMMAND_LEN);
659
660 irsnd_buffer[0] = ((address & 0x000F) << 4) | (command & 0x0F00) >> 8; // AAAACCCC
661 irsnd_buffer[1] = (command & 0x00FF); // CCCCCCCC
662
663 irsnd_busy = TRUE;
664 break;
665 }
666 #endif
667 #if IRSND_SUPPORT_NIKON_PROTOCOL == 1
668 case IRMP_NIKON_PROTOCOL:
669 {
670 irsnd_buffer[0] = (irmp_data_p->command & 0x0003) << 6; // CC
671 irsnd_busy = TRUE;
672 break;
673 }
674 #endif
675 default:
676 {
677 break;
678 }
679 }
680
681 return irsnd_busy;
682 }
683
684 /*---------------------------------------------------------------------------------------------------------------------------------------------------
685 * ISR routine
686 * @details ISR routine, called 10000 times per second
687 *---------------------------------------------------------------------------------------------------------------------------------------------------
688 */
689 uint8_t
690 irsnd_ISR (void)
691 {
692 static uint8_t current_bit = 0xFF;
693 static uint8_t pulse_counter;
694 static IRSND_PAUSE_LEN pause_counter;
695 static uint8_t startbit_pulse_len;
696 static IRSND_PAUSE_LEN startbit_pause_len;
697 static uint8_t pulse_1_len;
698 static uint8_t pause_1_len;
699 static uint8_t pulse_0_len;
700 static uint8_t pause_0_len;
701 static uint8_t has_stop_bit;
702 static uint8_t new_frame = TRUE;
703 static uint8_t complete_data_len;
704 static uint8_t n_auto_repetitions; // number of auto_repetitions
705 static uint8_t auto_repetition_counter; // auto_repetition counter
706 static uint16_t auto_repetition_pause_len; // pause before auto_repetition, uint16_t!
707 static uint16_t auto_repetition_pause_counter; // pause before auto_repetition, uint16_t!
708 static uint8_t n_repeat_frames; // number of repeat frames
709 static uint8_t repeat_counter; // repeat counter
710 static uint16_t repeat_frame_pause_len; // pause before repeat, uint16_t!
711 static uint16_t packet_repeat_pause_counter; // pause before repeat, uint16_t!
712 #if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1
713 static uint8_t last_bit_value;
714 #endif
715 static uint8_t pulse_len = 0xFF;
716 static IRSND_PAUSE_LEN pause_len = 0xFF;
717
718 if (irsnd_busy)
719 {
720 if (current_bit == 0xFF && new_frame) // start of transmission...
721 {
722 if (auto_repetition_counter > 0)
723 {
724 auto_repetition_pause_counter++;
725
726 if (auto_repetition_pause_counter >= auto_repetition_pause_len)
727 {
728 auto_repetition_pause_counter = 0;
729
730 if (irsnd_protocol == IRMP_DENON_PROTOCOL)
731 {
732 current_bit = 16;
733 complete_data_len = 2 * DENON_COMPLETE_DATA_LEN + 1;
734 }
735 else if (irsnd_protocol == IRMP_GRUNDIG_PROTOCOL) // n'th grundig info frame
736 {
737 current_bit = 15;
738 complete_data_len = 16 + GRUNDIG_COMPLETE_DATA_LEN;
739 }
740 else if (irsnd_protocol == IRMP_NOKIA_PROTOCOL) // n'th nokia info frame
741 {
742 if (auto_repetition_counter + 1 < n_auto_repetitions)
743 {
744 current_bit = 23;
745 complete_data_len = 24 + NOKIA_COMPLETE_DATA_LEN;
746 }
747 else // nokia stop frame
748 {
749 current_bit = 0xFF;
750 complete_data_len = NOKIA_COMPLETE_DATA_LEN;
751 }
752 }
753 }
754 else
755 {
756 #ifdef DEBUG
757 if (irsnd_is_on)
758 {
759 putchar ('0');
760 }
761 else
762 {
763 putchar ('1');
764 }
765 #endif
766 return irsnd_busy;
767 }
768 }
769 else if (repeat_counter > 0 && packet_repeat_pause_counter < repeat_frame_pause_len)
770 {
771 packet_repeat_pause_counter++;
772
773 #ifdef DEBUG
774 if (irsnd_is_on)
775 {
776 putchar ('0');
777 }
778 else
779 {
780 putchar ('1');
781 }
782 #endif
783 return irsnd_busy;
784 }
785 else
786 {
787 n_repeat_frames = irsnd_repeat;
788 packet_repeat_pause_counter = 0;
789 pulse_counter = 0;
790 pause_counter = 0;
791
792 switch (irsnd_protocol)
793 {
794 #if IRSND_SUPPORT_SIRCS_PROTOCOL == 1
795 case IRMP_SIRCS_PROTOCOL:
796 {
797 startbit_pulse_len = SIRCS_START_BIT_PULSE_LEN;
798 startbit_pause_len = SIRCS_START_BIT_PAUSE_LEN - 1;
799 pulse_1_len = SIRCS_1_PULSE_LEN;
800 pause_1_len = SIRCS_PAUSE_LEN - 1;
801 pulse_0_len = SIRCS_0_PULSE_LEN;
802 pause_0_len = SIRCS_PAUSE_LEN - 1;
803 has_stop_bit = SIRCS_STOP_BIT;
804 complete_data_len = SIRCS_MINIMUM_DATA_LEN + sircs_additional_bitlen;
805 n_auto_repetitions = (repeat_counter == 0) ? SIRCS_FRAMES : 1; // 3 frames auto repetition if first frame
806 auto_repetition_pause_len = SIRCS_AUTO_REPETITION_PAUSE_LEN; // 25ms pause
807 repeat_frame_pause_len = SIRCS_FRAME_REPEAT_PAUSE_LEN;
808 irsnd_set_freq (IRSND_FREQ_40_KHZ);
809 break;
810 }
811 #endif
812 #if IRSND_SUPPORT_NEC_PROTOCOL == 1
813 case IRMP_NEC_PROTOCOL:
814 {
815 startbit_pulse_len = NEC_START_BIT_PULSE_LEN;
816
817 if (repeat_counter > 0)
818 {
819 startbit_pause_len = NEC_REPEAT_START_BIT_PAUSE_LEN - 1;
820 complete_data_len = 0;
821 }
822 else
823 {
824 startbit_pause_len = NEC_START_BIT_PAUSE_LEN - 1;
825 complete_data_len = NEC_COMPLETE_DATA_LEN;
826 }
827
828 pulse_1_len = NEC_PULSE_LEN;
829 pause_1_len = NEC_1_PAUSE_LEN - 1;
830 pulse_0_len = NEC_PULSE_LEN;
831 pause_0_len = NEC_0_PAUSE_LEN - 1;
832 has_stop_bit = NEC_STOP_BIT;
833 n_auto_repetitions = 1; // 1 frame
834 auto_repetition_pause_len = 0;
835 repeat_frame_pause_len = NEC_FRAME_REPEAT_PAUSE_LEN;
836 irsnd_set_freq (IRSND_FREQ_38_KHZ);
837 break;
838 }
839 #endif
840 #if IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1
841 case IRMP_SAMSUNG_PROTOCOL:
842 {
843 startbit_pulse_len = SAMSUNG_START_BIT_PULSE_LEN;
844 startbit_pause_len = SAMSUNG_START_BIT_PAUSE_LEN - 1;
845 pulse_1_len = SAMSUNG_PULSE_LEN;
846 pause_1_len = SAMSUNG_1_PAUSE_LEN - 1;
847 pulse_0_len = SAMSUNG_PULSE_LEN;
848 pause_0_len = SAMSUNG_0_PAUSE_LEN - 1;
849 has_stop_bit = SAMSUNG_STOP_BIT;
850 complete_data_len = SAMSUNG_COMPLETE_DATA_LEN;
851 n_auto_repetitions = 1; // 1 frame
852 auto_repetition_pause_len = 0;
853 repeat_frame_pause_len = SAMSUNG_FRAME_REPEAT_PAUSE_LEN;
854 irsnd_set_freq (IRSND_FREQ_38_KHZ);
855 break;
856 }
857
858 case IRMP_SAMSUNG32_PROTOCOL:
859 {
860 startbit_pulse_len = SAMSUNG_START_BIT_PULSE_LEN;
861 startbit_pause_len = SAMSUNG_START_BIT_PAUSE_LEN - 1;
862 pulse_1_len = SAMSUNG_PULSE_LEN;
863 pause_1_len = SAMSUNG_1_PAUSE_LEN - 1;
864 pulse_0_len = SAMSUNG_PULSE_LEN;
865 pause_0_len = SAMSUNG_0_PAUSE_LEN - 1;
866 has_stop_bit = SAMSUNG_STOP_BIT;
867 complete_data_len = SAMSUNG32_COMPLETE_DATA_LEN;
868 n_auto_repetitions = SAMSUNG32_FRAMES; // 2 frames
869 auto_repetition_pause_len = SAMSUNG32_AUTO_REPETITION_PAUSE_LEN; // 47 ms pause
870 repeat_frame_pause_len = SAMSUNG32_FRAME_REPEAT_PAUSE_LEN;
871 irsnd_set_freq (IRSND_FREQ_38_KHZ);
872 break;
873 }
874 #endif
875 #if IRSND_SUPPORT_MATSUSHITA_PROTOCOL == 1
876 case IRMP_MATSUSHITA_PROTOCOL:
877 {
878 startbit_pulse_len = MATSUSHITA_START_BIT_PULSE_LEN;
879 startbit_pause_len = MATSUSHITA_START_BIT_PAUSE_LEN - 1;
880 pulse_1_len = MATSUSHITA_PULSE_LEN;
881 pause_1_len = MATSUSHITA_1_PAUSE_LEN - 1;
882 pulse_0_len = MATSUSHITA_PULSE_LEN;
883 pause_0_len = MATSUSHITA_0_PAUSE_LEN - 1;
884 has_stop_bit = MATSUSHITA_STOP_BIT;
885 complete_data_len = MATSUSHITA_COMPLETE_DATA_LEN;
886 n_auto_repetitions = 1; // 1 frame
887 auto_repetition_pause_len = 0;
888 repeat_frame_pause_len = MATSUSHITA_FRAME_REPEAT_PAUSE_LEN;
889 irsnd_set_freq (IRSND_FREQ_36_KHZ);
890 break;
891 }
892 #endif
893 #if IRSND_SUPPORT_KASEIKYO_PROTOCOL == 1
894 case IRMP_KASEIKYO_PROTOCOL:
895 {
896 startbit_pulse_len = KASEIKYO_START_BIT_PULSE_LEN;
897 startbit_pause_len = KASEIKYO_START_BIT_PAUSE_LEN - 1;
898 pulse_1_len = KASEIKYO_PULSE_LEN;
899 pause_1_len = KASEIKYO_1_PAUSE_LEN - 1;
900 pulse_0_len = KASEIKYO_PULSE_LEN;
901 pause_0_len = KASEIKYO_0_PAUSE_LEN - 1;
902 has_stop_bit = KASEIKYO_STOP_BIT;
903 complete_data_len = KASEIKYO_COMPLETE_DATA_LEN;
904 n_auto_repetitions = (repeat_counter == 0) ? KASEIKYO_FRAMES : 1; // 2 frames auto repetition if first frame
905 auto_repetition_pause_len = KASEIKYO_AUTO_REPETITION_PAUSE_LEN; // 75 ms pause
906 repeat_frame_pause_len = KASEIKYO_FRAME_REPEAT_PAUSE_LEN;
907 irsnd_set_freq (IRSND_FREQ_38_KHZ);
908 break;
909 }
910 #endif
911 #if IRSND_SUPPORT_RECS80_PROTOCOL == 1
912 case IRMP_RECS80_PROTOCOL:
913 {
914 startbit_pulse_len = RECS80_START_BIT_PULSE_LEN;
915 startbit_pause_len = RECS80_START_BIT_PAUSE_LEN - 1;
916 pulse_1_len = RECS80_PULSE_LEN;
917 pause_1_len = RECS80_1_PAUSE_LEN - 1;
918 pulse_0_len = RECS80_PULSE_LEN;
919 pause_0_len = RECS80_0_PAUSE_LEN - 1;
920 has_stop_bit = RECS80_STOP_BIT;
921 complete_data_len = RECS80_COMPLETE_DATA_LEN;
922 n_auto_repetitions = 1; // 1 frame
923 auto_repetition_pause_len = 0;
924 repeat_frame_pause_len = RECS80_FRAME_REPEAT_PAUSE_LEN;
925 irsnd_set_freq (IRSND_FREQ_38_KHZ);
926 break;
927 }
928 #endif
929 #if IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1
930 case IRMP_RECS80EXT_PROTOCOL:
931 {
932 startbit_pulse_len = RECS80EXT_START_BIT_PULSE_LEN;
933 startbit_pause_len = RECS80EXT_START_BIT_PAUSE_LEN - 1;
934 pulse_1_len = RECS80EXT_PULSE_LEN;
935 pause_1_len = RECS80EXT_1_PAUSE_LEN - 1;
936 pulse_0_len = RECS80EXT_PULSE_LEN;
937 pause_0_len = RECS80EXT_0_PAUSE_LEN - 1;
938 has_stop_bit = RECS80EXT_STOP_BIT;
939 complete_data_len = RECS80EXT_COMPLETE_DATA_LEN;
940 n_auto_repetitions = 1; // 1 frame
941 auto_repetition_pause_len = 0;
942 repeat_frame_pause_len = RECS80EXT_FRAME_REPEAT_PAUSE_LEN;
943 irsnd_set_freq (IRSND_FREQ_38_KHZ);
944 break;
945 }
946 #endif
947 #if IRSND_SUPPORT_RC5_PROTOCOL == 1
948 case IRMP_RC5_PROTOCOL:
949 {
950 startbit_pulse_len = RC5_BIT_LEN;
951 startbit_pause_len = RC5_BIT_LEN;
952 pulse_len = RC5_BIT_LEN;
953 pause_len = RC5_BIT_LEN;
954 has_stop_bit = RC5_STOP_BIT;
955 complete_data_len = RC5_COMPLETE_DATA_LEN;
956 n_auto_repetitions = 1; // 1 frame
957 auto_repetition_pause_len = 0;
958 repeat_frame_pause_len = RC5_FRAME_REPEAT_PAUSE_LEN;
959 irsnd_set_freq (IRSND_FREQ_36_KHZ);
960 break;
961 }
962 #endif
963 #if IRSND_SUPPORT_RC6_PROTOCOL == 1
964 case IRMP_RC6_PROTOCOL:
965 {
966 startbit_pulse_len = RC6_START_BIT_PULSE_LEN;
967 startbit_pause_len = RC6_START_BIT_PAUSE_LEN - 1;
968 pulse_len = RC6_BIT_LEN;
969 pause_len = RC6_BIT_LEN;
970 has_stop_bit = RC6_STOP_BIT;
971 complete_data_len = RC6_COMPLETE_DATA_LEN_SHORT;
972 n_auto_repetitions = 1; // 1 frame
973 auto_repetition_pause_len = 0;
974 repeat_frame_pause_len = RC6_FRAME_REPEAT_PAUSE_LEN;
975 irsnd_set_freq (IRSND_FREQ_36_KHZ);
976 break;
977 }
978 #endif
979 #if IRSND_SUPPORT_RC6A_PROTOCOL == 1
980 case IRMP_RC6A_PROTOCOL:
981 {
982 startbit_pulse_len = RC6_START_BIT_PULSE_LEN;
983 startbit_pause_len = RC6_START_BIT_PAUSE_LEN - 1;
984 pulse_len = RC6_BIT_LEN;
985 pause_len = RC6_BIT_LEN;
986 has_stop_bit = RC6_STOP_BIT;
987 complete_data_len = RC6_COMPLETE_DATA_LEN_LONG;
988 n_auto_repetitions = 1; // 1 frame
989 auto_repetition_pause_len = 0;
990 repeat_frame_pause_len = RC6_FRAME_REPEAT_PAUSE_LEN;
991 irsnd_set_freq (IRSND_FREQ_36_KHZ);
992 break;
993 }
994 #endif
995 #if IRSND_SUPPORT_DENON_PROTOCOL == 1
996 case IRMP_DENON_PROTOCOL:
997 {
998 startbit_pulse_len = 0x00;
999 startbit_pause_len = 0x00;
1000 pulse_1_len = DENON_PULSE_LEN;
1001 pause_1_len = DENON_1_PAUSE_LEN - 1;
1002 pulse_0_len = DENON_PULSE_LEN;
1003 pause_0_len = DENON_0_PAUSE_LEN - 1;
1004 has_stop_bit = DENON_STOP_BIT;
1005 complete_data_len = DENON_COMPLETE_DATA_LEN;
1006 n_auto_repetitions = DENON_FRAMES; // 2 frames, 2nd with inverted command
1007 auto_repetition_pause_len = DENON_AUTO_REPETITION_PAUSE_LEN; // 65 ms pause after 1st frame
1008 repeat_frame_pause_len = DENON_FRAME_REPEAT_PAUSE_LEN;
1009 irsnd_set_freq (IRSND_FREQ_36_KHZ); // in theory 32kHz, in practice 36kHz is better
1010 break;
1011 }
1012 #endif
1013 #if IRSND_SUPPORT_NUBERT_PROTOCOL == 1
1014 case IRMP_NUBERT_PROTOCOL:
1015 {
1016 startbit_pulse_len = NUBERT_START_BIT_PULSE_LEN;
1017 startbit_pause_len = NUBERT_START_BIT_PAUSE_LEN - 1;
1018 pulse_1_len = NUBERT_1_PULSE_LEN;
1019 pause_1_len = NUBERT_1_PAUSE_LEN - 1;
1020 pulse_0_len = NUBERT_0_PULSE_LEN;
1021 pause_0_len = NUBERT_0_PAUSE_LEN - 1;
1022 has_stop_bit = NUBERT_STOP_BIT;
1023 complete_data_len = NUBERT_COMPLETE_DATA_LEN;
1024 n_auto_repetitions = NUBERT_FRAMES; // 2 frames
1025 auto_repetition_pause_len = NUBERT_AUTO_REPETITION_PAUSE_LEN; // 35 ms pause
1026 repeat_frame_pause_len = NUBERT_FRAME_REPEAT_PAUSE_LEN;
1027 irsnd_set_freq (IRSND_FREQ_36_KHZ);
1028 break;
1029 }
1030 #endif
1031 #if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1
1032 case IRMP_BANG_OLUFSEN_PROTOCOL:
1033 {
1034 startbit_pulse_len = BANG_OLUFSEN_START_BIT1_PULSE_LEN;
1035 startbit_pause_len = BANG_OLUFSEN_START_BIT1_PAUSE_LEN - 1;
1036 pulse_1_len = BANG_OLUFSEN_PULSE_LEN;
1037 pause_1_len = BANG_OLUFSEN_1_PAUSE_LEN - 1;
1038 pulse_0_len = BANG_OLUFSEN_PULSE_LEN;
1039 pause_0_len = BANG_OLUFSEN_0_PAUSE_LEN - 1;
1040 has_stop_bit = BANG_OLUFSEN_STOP_BIT;
1041 complete_data_len = BANG_OLUFSEN_COMPLETE_DATA_LEN;
1042 n_auto_repetitions = 1; // 1 frame
1043 auto_repetition_pause_len = 0;
1044 repeat_frame_pause_len = BANG_OLUFSEN_FRAME_REPEAT_PAUSE_LEN;
1045 last_bit_value = 0;
1046 irsnd_set_freq (IRSND_FREQ_455_KHZ);
1047 break;
1048 }
1049 #endif
1050 #if IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1
1051 case IRMP_GRUNDIG_PROTOCOL:
1052 {
1053 startbit_pulse_len = GRUNDIG_OR_NOKIA_BIT_LEN;
1054 startbit_pause_len = GRUNDIG_OR_NOKIA_PRE_PAUSE_LEN - 1;
1055 pulse_len = GRUNDIG_OR_NOKIA_BIT_LEN;
1056 pause_len = GRUNDIG_OR_NOKIA_BIT_LEN;
1057 has_stop_bit = GRUNDIG_OR_NOKIA_STOP_BIT;
1058 complete_data_len = GRUNDIG_COMPLETE_DATA_LEN;
1059 n_auto_repetitions = GRUNDIG_FRAMES; // 2 frames
1060 auto_repetition_pause_len = GRUNDIG_AUTO_REPETITION_PAUSE_LEN; // 20m sec pause
1061 repeat_frame_pause_len = GRUNDIG_OR_NOKIA_FRAME_REPEAT_PAUSE_LEN; // 117 msec pause
1062 irsnd_set_freq (IRSND_FREQ_38_KHZ);
1063
1064 break;
1065 }
1066 #endif
1067 #if IRSND_SUPPORT_NOKIA_PROTOCOL == 1
1068 case IRMP_NOKIA_PROTOCOL:
1069 {
1070 startbit_pulse_len = GRUNDIG_OR_NOKIA_BIT_LEN;
1071 startbit_pause_len = GRUNDIG_OR_NOKIA_PRE_PAUSE_LEN - 1;
1072 pulse_len = GRUNDIG_OR_NOKIA_BIT_LEN;
1073 pause_len = GRUNDIG_OR_NOKIA_BIT_LEN;
1074 has_stop_bit = GRUNDIG_OR_NOKIA_STOP_BIT;
1075 complete_data_len = NOKIA_COMPLETE_DATA_LEN;
1076 n_auto_repetitions = NOKIA_FRAMES; // 2 frames
1077 auto_repetition_pause_len = NOKIA_AUTO_REPETITION_PAUSE_LEN; // 20 msec pause
1078 repeat_frame_pause_len = GRUNDIG_OR_NOKIA_FRAME_REPEAT_PAUSE_LEN; // 117 msec pause
1079 irsnd_set_freq (IRSND_FREQ_38_KHZ);
1080 break;
1081 }
1082 #endif
1083 #if IRSND_SUPPORT_SIEMENS_PROTOCOL == 1
1084 case IRMP_SIEMENS_PROTOCOL:
1085 {
1086 startbit_pulse_len = SIEMENS_BIT_LEN;
1087 startbit_pause_len = SIEMENS_BIT_LEN;
1088 pulse_len = SIEMENS_BIT_LEN;
1089 pause_len = SIEMENS_BIT_LEN;
1090 has_stop_bit = SIEMENS_STOP_BIT;
1091 complete_data_len = SIEMENS_COMPLETE_DATA_LEN - 1;
1092 n_auto_repetitions = 1; // 1 frame
1093 auto_repetition_pause_len = 0;
1094 repeat_frame_pause_len = SIEMENS_FRAME_REPEAT_PAUSE_LEN;
1095 irsnd_set_freq (IRSND_FREQ_36_KHZ);
1096 break;
1097 }
1098 #endif
1099 #if IRSND_SUPPORT_FDC_PROTOCOL == 1
1100 case IRMP_FDC_PROTOCOL:
1101 {
1102 startbit_pulse_len = FDC_START_BIT_PULSE_LEN;
1103 startbit_pause_len = FDC_START_BIT_PAUSE_LEN - 1;
1104 complete_data_len = FDC_COMPLETE_DATA_LEN;
1105 pulse_1_len = FDC_PULSE_LEN;
1106 pause_1_len = FDC_1_PAUSE_LEN - 1;
1107 pulse_0_len = FDC_PULSE_LEN;
1108 pause_0_len = FDC_0_PAUSE_LEN - 1;
1109 has_stop_bit = FDC_STOP_BIT;
1110 n_auto_repetitions = 1; // 1 frame
1111 auto_repetition_pause_len = 0;
1112 repeat_frame_pause_len = FDC_FRAME_REPEAT_PAUSE_LEN;
1113 irsnd_set_freq (IRSND_FREQ_38_KHZ);
1114 break;
1115 }
1116 #endif
1117 #if IRSND_SUPPORT_RCCAR_PROTOCOL == 1
1118 case IRMP_RCCAR_PROTOCOL:
1119 {
1120 startbit_pulse_len = RCCAR_START_BIT_PULSE_LEN;
1121 startbit_pause_len = RCCAR_START_BIT_PAUSE_LEN - 1;
1122 complete_data_len = RCCAR_COMPLETE_DATA_LEN;
1123 pulse_1_len = RCCAR_PULSE_LEN;
1124 pause_1_len = RCCAR_1_PAUSE_LEN - 1;
1125 pulse_0_len = RCCAR_PULSE_LEN;
1126 pause_0_len = RCCAR_0_PAUSE_LEN - 1;
1127 has_stop_bit = RCCAR_STOP_BIT;
1128 n_auto_repetitions = 1; // 1 frame
1129 auto_repetition_pause_len = 0;
1130 repeat_frame_pause_len = RCCAR_FRAME_REPEAT_PAUSE_LEN;
1131 irsnd_set_freq (IRSND_FREQ_38_KHZ);
1132 break;
1133 }
1134 #endif
1135 #if IRSND_SUPPORT_JVC_PROTOCOL == 1
1136 case IRMP_JVC_PROTOCOL:
1137 {
1138 if (repeat_counter != 0) // skip start bit if repetition frame
1139 {
1140 current_bit = 0;
1141 }
1142
1143 startbit_pulse_len = JVC_START_BIT_PULSE_LEN;
1144 startbit_pause_len = JVC_START_BIT_PAUSE_LEN - 1;
1145 complete_data_len = JVC_COMPLETE_DATA_LEN;
1146 pulse_1_len = JVC_PULSE_LEN;
1147 pause_1_len = JVC_1_PAUSE_LEN - 1;
1148 pulse_0_len = JVC_PULSE_LEN;
1149 pause_0_len = JVC_0_PAUSE_LEN - 1;
1150 has_stop_bit = JVC_STOP_BIT;
1151 n_auto_repetitions = 1; // 1 frame
1152 auto_repetition_pause_len = 0;
1153 repeat_frame_pause_len = JVC_FRAME_REPEAT_PAUSE_LEN;
1154 irsnd_set_freq (IRSND_FREQ_38_KHZ);
1155
1156 break;
1157 }
1158 #endif
1159 #if IRSND_SUPPORT_NIKON_PROTOCOL == 1
1160 case IRMP_NIKON_PROTOCOL:
1161 {
1162 startbit_pulse_len = NIKON_START_BIT_PULSE_LEN;
1163 startbit_pause_len = 271 - 1; // NIKON_START_BIT_PAUSE_LEN;
1164 complete_data_len = NIKON_COMPLETE_DATA_LEN;
1165 pulse_1_len = NIKON_PULSE_LEN;
1166 pause_1_len = NIKON_1_PAUSE_LEN - 1;
1167 pulse_0_len = NIKON_PULSE_LEN;
1168 pause_0_len = NIKON_0_PAUSE_LEN - 1;
1169 has_stop_bit = NIKON_STOP_BIT;
1170 n_auto_repetitions = 1; // 1 frame
1171 auto_repetition_pause_len = 0;
1172 repeat_frame_pause_len = NIKON_FRAME_REPEAT_PAUSE_LEN;
1173 irsnd_set_freq (IRSND_FREQ_38_KHZ);
1174
1175 break;
1176 }
1177 #endif
1178 default:
1179 {
1180 irsnd_busy = FALSE;
1181 break;
1182 }
1183 }
1184 }
1185 }
1186
1187 if (irsnd_busy)
1188 {
1189 new_frame = FALSE;
1190
1191 switch (irsnd_protocol)
1192 {
1193 #if IRSND_SUPPORT_SIRCS_PROTOCOL == 1
1194 case IRMP_SIRCS_PROTOCOL:
1195 #endif
1196 #if IRSND_SUPPORT_NEC_PROTOCOL == 1
1197 case IRMP_NEC_PROTOCOL:
1198 #endif
1199 #if IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1
1200 case IRMP_SAMSUNG_PROTOCOL:
1201 case IRMP_SAMSUNG32_PROTOCOL:
1202 #endif
1203 #if IRSND_SUPPORT_MATSUSHITA_PROTOCOL == 1
1204 case IRMP_MATSUSHITA_PROTOCOL:
1205 #endif
1206 #if IRSND_SUPPORT_KASEIKYO_PROTOCOL == 1
1207 case IRMP_KASEIKYO_PROTOCOL:
1208 #endif
1209 #if IRSND_SUPPORT_RECS80_PROTOCOL == 1
1210 case IRMP_RECS80_PROTOCOL:
1211 #endif
1212 #if IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1
1213 case IRMP_RECS80EXT_PROTOCOL:
1214 #endif
1215 #if IRSND_SUPPORT_DENON_PROTOCOL == 1
1216 case IRMP_DENON_PROTOCOL:
1217 #endif
1218 #if IRSND_SUPPORT_NUBERT_PROTOCOL == 1
1219 case IRMP_NUBERT_PROTOCOL:
1220 #endif
1221 #if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1
1222 case IRMP_BANG_OLUFSEN_PROTOCOL:
1223 #endif
1224 #if IRSND_SUPPORT_FDC_PROTOCOL == 1
1225 case IRMP_FDC_PROTOCOL:
1226 #endif
1227 #if IRSND_SUPPORT_RCCAR_PROTOCOL == 1
1228 case IRMP_RCCAR_PROTOCOL:
1229 #endif
1230 #if IRSND_SUPPORT_JVC_PROTOCOL == 1
1231 case IRMP_JVC_PROTOCOL:
1232 #endif
1233 #if IRSND_SUPPORT_NIKON_PROTOCOL == 1
1234 case IRMP_NIKON_PROTOCOL:
1235 #endif
1236
1237
1238 #if IRSND_SUPPORT_SIRCS_PROTOCOL == 1 || IRSND_SUPPORT_NEC_PROTOCOL == 1 || IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1 || IRSND_SUPPORT_MATSUSHITA_PROTOCOL == 1 || \
1239 IRSND_SUPPORT_KASEIKYO_PROTOCOL == 1 || IRSND_SUPPORT_RECS80_PROTOCOL == 1 || IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1 || IRSND_SUPPORT_DENON_PROTOCOL == 1 || \
1240 IRSND_SUPPORT_NUBERT_PROTOCOL == 1 || IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1 || IRSND_SUPPORT_FDC_PROTOCOL == 1 || IRSND_SUPPORT_RCCAR_PROTOCOL == 1 || \
1241 IRSND_SUPPORT_JVC_PROTOCOL == 1 || IRSND_SUPPORT_NIKON_PROTOCOL == 1
1242 {
1243 if (pulse_counter == 0)
1244 {
1245 if (current_bit == 0xFF) // send start bit
1246 {
1247 pulse_len = startbit_pulse_len;
1248 pause_len = startbit_pause_len;
1249 }
1250 else if (current_bit < complete_data_len) // send n'th bit
1251 {
1252 #if IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1
1253 if (irsnd_protocol == IRMP_SAMSUNG_PROTOCOL)
1254 {
1255 if (current_bit < SAMSUNG_ADDRESS_LEN) // send address bits
1256 {
1257 pulse_len = SAMSUNG_PULSE_LEN;
1258 pause_len = (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8)))) ?
1259 (SAMSUNG_1_PAUSE_LEN - 1) : (SAMSUNG_0_PAUSE_LEN - 1);
1260 }
1261 else if (current_bit == SAMSUNG_ADDRESS_LEN) // send SYNC bit (16th bit)
1262 {
1263 pulse_len = SAMSUNG_PULSE_LEN;
1264 pause_len = SAMSUNG_START_BIT_PAUSE_LEN - 1;
1265 }
1266 else if (current_bit < SAMSUNG_COMPLETE_DATA_LEN) // send n'th bit
1267 {
1268 uint8_t cur_bit = current_bit - 1; // sync skipped, offset = -1 !
1269
1270 pulse_len = SAMSUNG_PULSE_LEN;
1271 pause_len = (irsnd_buffer[cur_bit / 8] & (1<<(7-(cur_bit % 8)))) ?
1272 (SAMSUNG_1_PAUSE_LEN - 1) : (SAMSUNG_0_PAUSE_LEN - 1);
1273 }
1274 }
1275 else
1276 #endif
1277
1278 #if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1
1279 if (irsnd_protocol == IRMP_BANG_OLUFSEN_PROTOCOL)
1280 {
1281 if (current_bit == 0) // send 2nd start bit
1282 {
1283 pulse_len = BANG_OLUFSEN_START_BIT2_PULSE_LEN;
1284 pause_len = BANG_OLUFSEN_START_BIT2_PAUSE_LEN - 1;
1285 }
1286 else if (current_bit == 1) // send 3rd start bit
1287 {
1288 pulse_len = BANG_OLUFSEN_START_BIT3_PULSE_LEN;
1289 pause_len = BANG_OLUFSEN_START_BIT3_PAUSE_LEN - 1;
1290 }
1291 else if (current_bit == 2) // send 4th start bit
1292 {
1293 pulse_len = BANG_OLUFSEN_START_BIT2_PULSE_LEN;
1294 pause_len = BANG_OLUFSEN_START_BIT2_PAUSE_LEN - 1;
1295 }
1296 else if (current_bit == 19) // send trailer bit
1297 {
1298 pulse_len = BANG_OLUFSEN_PULSE_LEN;
1299 pause_len = BANG_OLUFSEN_TRAILER_BIT_PAUSE_LEN - 1;
1300 }
1301 else if (current_bit < BANG_OLUFSEN_COMPLETE_DATA_LEN) // send n'th bit
1302 {
1303 uint8_t cur_bit_value = (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8)))) ? 1 : 0;
1304 pulse_len = BANG_OLUFSEN_PULSE_LEN;
1305
1306 if (cur_bit_value == last_bit_value)
1307 {
1308 pause_len = BANG_OLUFSEN_R_PAUSE_LEN - 1;
1309 }
1310 else
1311 {
1312 pause_len = cur_bit_value ? (BANG_OLUFSEN_1_PAUSE_LEN - 1) : (BANG_OLUFSEN_0_PAUSE_LEN - 1);
1313 last_bit_value = cur_bit_value;
1314 }
1315 }
1316 }
1317 else
1318 #endif
1319 if (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8))))
1320 {
1321 pulse_len = pulse_1_len;
1322 pause_len = pause_1_len;
1323 }
1324 else
1325 {
1326 pulse_len = pulse_0_len;
1327 pause_len = pause_0_len;
1328 }
1329 }
1330 else if (has_stop_bit) // send stop bit
1331 {
1332 pulse_len = pulse_0_len;
1333
1334 if (auto_repetition_counter < n_auto_repetitions)
1335 {
1336 pause_len = pause_0_len;
1337 }
1338 else
1339 {
1340 pause_len = 255; // last frame: pause of 255
1341 }
1342 }
1343 }
1344
1345 if (pulse_counter < pulse_len)
1346 {
1347 if (pulse_counter == 0)
1348 {
1349 irsnd_on ();
1350 }
1351 pulse_counter++;
1352 }
1353 else if (pause_counter < pause_len)
1354 {
1355 if (pause_counter == 0)
1356 {
1357 irsnd_off ();
1358 }
1359 pause_counter++;
1360 }
1361 else
1362 {
1363 current_bit++;
1364
1365 if (current_bit >= complete_data_len + has_stop_bit)
1366 {
1367 current_bit = 0xFF;
1368 auto_repetition_counter++;
1369
1370 if (auto_repetition_counter == n_auto_repetitions)
1371 {
1372 irsnd_busy = FALSE;
1373 auto_repetition_counter = 0;
1374 }
1375 new_frame = TRUE;
1376 }
1377
1378 pulse_counter = 0;
1379 pause_counter = 0;
1380 }
1381 break;
1382 }
1383 #endif
1384
1385 #if IRSND_SUPPORT_RC5_PROTOCOL == 1
1386 case IRMP_RC5_PROTOCOL:
1387 #endif
1388 #if IRSND_SUPPORT_RC6_PROTOCOL == 1
1389 case IRMP_RC6_PROTOCOL:
1390 #endif
1391 #if IRSND_SUPPORT_RC6A_PROTOCOL == 1
1392 case IRMP_RC6A_PROTOCOL:
1393 #endif
1394 #if IRSND_SUPPORT_SIEMENS_PROTOCOL == 1
1395 case IRMP_SIEMENS_PROTOCOL:
1396 #endif
1397 #if IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1
1398 case IRMP_GRUNDIG_PROTOCOL:
1399 #endif
1400 #if IRSND_SUPPORT_NOKIA_PROTOCOL == 1
1401 case IRMP_NOKIA_PROTOCOL:
1402 #endif
1403
1404 #if IRSND_SUPPORT_RC5_PROTOCOL == 1 || IRSND_SUPPORT_RC6_PROTOCOL == 1 || IRSND_SUPPORT_RC6A_PROTOCOL == 1 || IRSND_SUPPORT_SIEMENS_PROTOCOL == 1 || \
1405 IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1 || IRSND_SUPPORT_NOKIA_PROTOCOL == 1
1406 {
1407 if (pulse_counter == pulse_len && pause_counter == pause_len)
1408 {
1409 current_bit++;
1410
1411 if (current_bit >= complete_data_len)
1412 {
1413 current_bit = 0xFF;
1414
1415 #if IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1 || IRSND_SUPPORT_NOKIA_PROTOCOL == 1
1416 if (irsnd_protocol == IRMP_GRUNDIG_PROTOCOL || irsnd_protocol == IRMP_NOKIA_PROTOCOL)
1417 {
1418 auto_repetition_counter++;
1419
1420 if (repeat_counter > 0)
1421 { // set 117 msec pause time
1422 auto_repetition_pause_len = GRUNDIG_OR_NOKIA_FRAME_REPEAT_PAUSE_LEN;
1423 }
1424
1425 if (repeat_counter < n_repeat_frames) // tricky: repeat n info frames per auto repetition before sending last stop frame
1426 {
1427 n_auto_repetitions++; // increment number of auto repetitions
1428 repeat_counter++;
1429 }
1430 else if (auto_repetition_counter == n_auto_repetitions)
1431 {
1432 irsnd_busy = FALSE;
1433 auto_repetition_counter = 0;
1434 }
1435 }
1436 else
1437 #endif
1438 {
1439 irsnd_busy = FALSE;
1440 }
1441
1442 new_frame = TRUE;
1443 irsnd_off ();
1444 }
1445
1446 pulse_counter = 0;
1447 pause_counter = 0;
1448 }
1449
1450 if (! new_frame)
1451 {
1452 uint8_t first_pulse;
1453
1454 #if IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1 || IRSND_SUPPORT_NOKIA_PROTOCOL == 1
1455 if (irsnd_protocol == IRMP_GRUNDIG_PROTOCOL || irsnd_protocol == IRMP_NOKIA_PROTOCOL)
1456 {
1457 if (current_bit == 0xFF || // start bit of start-frame
1458 (irsnd_protocol == IRMP_GRUNDIG_PROTOCOL && current_bit == 15) || // start bit of info-frame (Grundig)
1459 (irsnd_protocol == IRMP_NOKIA_PROTOCOL && (current_bit == 23 || current_bit == 47))) // start bit of info- or stop-frame (Nokia)
1460 {
1461 pulse_len = startbit_pulse_len;
1462 pause_len = startbit_pause_len;
1463 first_pulse = TRUE;
1464 }
1465 else // send n'th bit
1466 {
1467 pulse_len = GRUNDIG_OR_NOKIA_BIT_LEN;
1468 pause_len = GRUNDIG_OR_NOKIA_BIT_LEN;
1469 first_pulse = (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8)))) ? TRUE : FALSE;
1470 }
1471 }
1472 else // if (irsnd_protocol == IRMP_RC5_PROTOCOL || irsnd_protocol == IRMP_RC6_PROTOCOL || irsnd_protocol == IRMP_RC6A_PROTOCOL ||
1473 // irsnd_protocol == IRMP_SIEMENS_PROTOCOL)
1474 #endif
1475 {
1476 if (current_bit == 0xFF) // 1 start bit
1477 {
1478 #if IRSND_SUPPORT_RC6_PROTOCOL == 1 || IRSND_SUPPORT_RC6A_PROTOCOL == 1
1479 if (irsnd_protocol == IRMP_RC6_PROTOCOL || irsnd_protocol == IRMP_RC6A_PROTOCOL)
1480 {
1481 pulse_len = startbit_pulse_len;
1482 pause_len = startbit_pause_len;
1483 }
1484 #endif
1485 first_pulse = TRUE;
1486 }
1487 else // send n'th bit
1488 {
1489 #if IRSND_SUPPORT_RC6_PROTOCOL == 1 || IRSND_SUPPORT_RC6A_PROTOCOL == 1
1490 if (irsnd_protocol == IRMP_RC6_PROTOCOL || irsnd_protocol == IRMP_RC6A_PROTOCOL)
1491 {
1492 pulse_len = RC6_BIT_LEN;
1493 pause_len = RC6_BIT_LEN;
1494
1495 if (irsnd_protocol == IRMP_RC6_PROTOCOL)
1496 {
1497 if (current_bit == 4) // toggle bit (double len)
1498 {
1499 pulse_len = 2 * RC6_BIT_LEN;
1500 pause_len = 2 * RC6_BIT_LEN;
1501 }
1502 }
1503 else // if (irsnd_protocol == IRMP_RC6A_PROTOCOL)
1504 {
1505 if (current_bit == 4) // toggle bit (double len)
1506 {
1507 pulse_len = 2 * RC6_BIT_LEN + RC6_BIT_LEN; // hack!
1508 pause_len = 2 * RC6_BIT_LEN;
1509 }
1510 else if (current_bit == 5) // toggle bit (double len)
1511 {
1512 pause_len = 2 * RC6_BIT_LEN;
1513 }
1514 }
1515 }
1516 #endif
1517 first_pulse = (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8)))) ? TRUE : FALSE;
1518 }
1519
1520 if (irsnd_protocol == IRMP_RC5_PROTOCOL)
1521 {
1522 first_pulse = first_pulse ? FALSE : TRUE;
1523 }
1524 }
1525
1526 if (first_pulse)
1527 {
1528 if (pulse_counter < pulse_len)
1529 {
1530 if (pulse_counter == 0)
1531 {
1532 irsnd_on ();
1533 }
1534 pulse_counter++;
1535 }
1536 else // if (pause_counter < pause_len)
1537 {
1538 if (pause_counter == 0)
1539 {
1540 irsnd_off ();
1541 }
1542 pause_counter++;
1543 }
1544 }
1545 else
1546 {
1547 if (pause_counter < pause_len)
1548 {
1549 if (pause_counter == 0)
1550 {
1551 irsnd_off ();
1552 }
1553 pause_counter++;
1554 }
1555 else // if (pulse_counter < pulse_len)
1556 {
1557 if (pulse_counter == 0)
1558 {
1559 irsnd_on ();
1560 }
1561 pulse_counter++;
1562 }
1563 }
1564 }
1565 break;
1566 }
1567 #endif // IRSND_SUPPORT_RC5_PROTOCOL == 1 || IRSND_SUPPORT_RC6_PROTOCOL == 1 || || IRSND_SUPPORT_RC6A_PROTOCOL == 1 || IRSND_SUPPORT_SIEMENS_PROTOCOL == 1 ||
1568 // IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1 || IRSND_SUPPORT_NOKIA_PROTOCOL == 1
1569
1570 default:
1571 {
1572 irsnd_busy = FALSE;
1573 break;
1574 }
1575 }
1576 }
1577
1578 if (! irsnd_busy)
1579 {
1580 if (repeat_counter < n_repeat_frames)
1581 {
1582 #if IRSND_SUPPORT_FDC_PROTOCOL == 1
1583 if (irsnd_protocol == IRMP_FDC_PROTOCOL)
1584 {
1585 irsnd_buffer[2] |= 0x0F;
1586 }
1587 #endif
1588 repeat_counter++;
1589 irsnd_busy = TRUE;
1590 }
1591 else
1592 {
1593 n_repeat_frames = 0;
1594 repeat_counter = 0;
1595 }
1596 }
1597 }
1598
1599 #ifdef DEBUG
1600 if (irsnd_is_on)
1601 {
1602 putchar ('0');
1603 }
1604 else
1605 {
1606 putchar ('1');
1607 }
1608 #endif
1609
1610 return irsnd_busy;
1611 }
1612
1613 #ifdef DEBUG
1614
1615 // main function - for unix/linux + windows only!
1616 // AVR: see main.c!
1617 // Compile it under linux with:
1618 // cc irsnd.c -o irsnd
1619 //
1620 // usage: ./irsnd protocol hex-address hex-command >filename
1621
1622 int
1623 main (int argc, char ** argv)
1624 {
1625 int idx;
1626 int protocol;
1627 int address;
1628 int command;
1629 IRMP_DATA irmp_data;
1630
1631 if (argc != 4 && argc != 5)
1632 {
1633 fprintf (stderr, "usage: %s protocol hex-address hex-command [repeat] > filename\n", argv[0]);
1634 return 1;
1635 }
1636
1637 if (sscanf (argv[1], "%d", &protocol) == 1 &&
1638 sscanf (argv[2], "%x", &address) == 1 &&
1639 sscanf (argv[3], "%x", &command) == 1)
1640 {
1641 irmp_data.protocol = protocol;
1642 irmp_data.address = address;
1643 irmp_data.command = command;
1644
1645 if (argc == 5)
1646 {
1647 irmp_data.flags = atoi (argv[4]);
1648 }
1649 else
1650 {
1651 irmp_data.flags = 0;
1652 }
1653
1654 irsnd_init ();
1655
1656 (void) irsnd_send_data (&irmp_data, TRUE);
1657
1658 while (irsnd_busy)
1659 {
1660 irsnd_ISR ();
1661 }
1662 for (idx = 0; idx < 20; idx++)
1663 {
1664 irsnd_ISR ();
1665 }
1666
1667 putchar ('\n');
1668 }
1669 else
1670 {
1671 fprintf (stderr, "%s: wrong arguments\n", argv[0]);
1672 return 1;
1673 }
1674 return 0;
1675 }
1676
1677 #endif // DEBUG