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