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