]> cloudbase.mooo.com Git - irmp.git/blame - irsnd.c
Version 1.4.0: Added Grundig + Nokia protocol
[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
d155e9ab 6 * $Id: irsnd.c,v 1.12 2010/05/26 08:34:30 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
d155e9ab 59#define SIRCS_FRAME_REPETITION_LEN (uint16_t)(F_INTERRUPTS * SIRCS_FRAME_REPETITION_TIME + 0.5) // use uint16_t!\r
4225a882 60\r
61#define NEC_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * NEC_START_BIT_PULSE_TIME + 0.5)\r
62#define NEC_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NEC_START_BIT_PAUSE_TIME + 0.5)\r
63#define NEC_PULSE_LEN (uint8_t)(F_INTERRUPTS * NEC_PULSE_TIME + 0.5)\r
64#define NEC_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NEC_1_PAUSE_TIME + 0.5)\r
65#define NEC_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NEC_0_PAUSE_TIME + 0.5)\r
66\r
67#define SAMSUNG_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PULSE_TIME + 0.5)\r
68#define SAMSUNG_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PAUSE_TIME + 0.5)\r
69#define SAMSUNG_PULSE_LEN (uint8_t)(F_INTERRUPTS * SAMSUNG_PULSE_TIME + 0.5)\r
70#define SAMSUNG_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * SAMSUNG_1_PAUSE_TIME + 0.5)\r
71#define SAMSUNG_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * SAMSUNG_0_PAUSE_TIME + 0.5)\r
72\r
d155e9ab 73#define SAMSUNG32_FRAME_REPETITION_LEN (uint16_t)(F_INTERRUPTS * SAMSUNG32_FRAME_REPETITION_TIME + 0.5) // use uint16_t!\r
5b437ff6 74\r
4225a882 75#define MATSUSHITA_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PULSE_TIME + 0.5)\r
76#define MATSUSHITA_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PAUSE_TIME + 0.5)\r
77#define MATSUSHITA_PULSE_LEN (uint8_t)(F_INTERRUPTS * MATSUSHITA_PULSE_TIME + 0.5)\r
78#define MATSUSHITA_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * MATSUSHITA_1_PAUSE_TIME + 0.5)\r
79#define MATSUSHITA_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * MATSUSHITA_0_PAUSE_TIME + 0.5)\r
80\r
81#define RECS80_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * RECS80_START_BIT_PULSE_TIME + 0.5)\r
82#define RECS80_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RECS80_START_BIT_PAUSE_TIME + 0.5)\r
83#define RECS80_PULSE_LEN (uint8_t)(F_INTERRUPTS * RECS80_PULSE_TIME + 0.5)\r
84#define RECS80_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RECS80_1_PAUSE_TIME + 0.5)\r
85#define RECS80_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RECS80_0_PAUSE_TIME + 0.5)\r
86\r
87#define RC5_START_BIT_LEN (uint8_t)(F_INTERRUPTS * RC5_BIT_TIME + 0.5)\r
88#define RC5_BIT_LEN (uint8_t)(F_INTERRUPTS * RC5_BIT_TIME + 0.5)\r
89\r
90#define RC6_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * RC6_START_BIT_PULSE_TIME + 0.5)\r
91#define RC6_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RC6_START_BIT_PAUSE_TIME + 0.5)\r
92#define RC6_TOGGLE_BIT_LEN (uint8_t)(F_INTERRUPTS * RC6_TOGGLE_BIT_TIME + 0.5)\r
93#define RC6_BIT_LEN (uint8_t)(F_INTERRUPTS * RC6_BIT_TIME + 0.5)\r
94\r
95#define DENON_PULSE_LEN (uint8_t)(F_INTERRUPTS * DENON_PULSE_TIME + 0.5)\r
96#define DENON_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * DENON_1_PAUSE_TIME + 0.5)\r
97#define DENON_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * DENON_0_PAUSE_TIME + 0.5)\r
d155e9ab 98#define DENON_FRAME_REPETITION_LEN (uint16_t)(F_INTERRUPTS * DENON_FRAME_REPETITION_TIME + 0.5) // use uint16_t!\r
4225a882 99\r
100#define RECS80EXT_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PULSE_TIME + 0.5)\r
101#define RECS80EXT_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PAUSE_TIME + 0.5)\r
102#define RECS80EXT_PULSE_LEN (uint8_t)(F_INTERRUPTS * RECS80EXT_PULSE_TIME + 0.5)\r
103#define RECS80EXT_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RECS80EXT_1_PAUSE_TIME + 0.5)\r
104#define RECS80EXT_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RECS80EXT_0_PAUSE_TIME + 0.5)\r
105\r
106#define NUBERT_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * NUBERT_START_BIT_PULSE_TIME + 0.5)\r
107#define NUBERT_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NUBERT_START_BIT_PAUSE_TIME + 0.5)\r
108#define NUBERT_1_PULSE_LEN (uint8_t)(F_INTERRUPTS * NUBERT_1_PULSE_TIME + 0.5)\r
109#define NUBERT_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NUBERT_1_PAUSE_TIME + 0.5)\r
110#define NUBERT_0_PULSE_LEN (uint8_t)(F_INTERRUPTS * NUBERT_0_PULSE_TIME + 0.5)\r
111#define NUBERT_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NUBERT_0_PAUSE_TIME + 0.5)\r
d155e9ab 112#define NUBERT_FRAME_REPETITION_LEN (uint16_t)(F_INTERRUPTS * NUBERT_FRAME_REPETITION_TIME + 0.5) // use uint16_t!\r
4225a882 113\r
5481e9cd 114#define BANG_OLUFSEN_START_BIT1_PULSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT1_PULSE_TIME + 0.5)\r
115#define BANG_OLUFSEN_START_BIT1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT1_PAUSE_TIME + 0.5)\r
116#define BANG_OLUFSEN_START_BIT2_PULSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT2_PULSE_TIME + 0.5)\r
117#define BANG_OLUFSEN_START_BIT2_PAUSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT2_PAUSE_TIME + 0.5)\r
118#define BANG_OLUFSEN_START_BIT3_PULSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT3_PULSE_TIME + 0.5)\r
119#define BANG_OLUFSEN_START_BIT3_PAUSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT3_PAUSE_TIME + 0.5)\r
120#define BANG_OLUFSEN_PULSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_PULSE_TIME + 0.5)\r
121#define BANG_OLUFSEN_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_1_PAUSE_TIME + 0.5)\r
122#define BANG_OLUFSEN_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_0_PAUSE_TIME + 0.5)\r
123#define BANG_OLUFSEN_R_PAUSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_R_PAUSE_TIME + 0.5)\r
124#define BANG_OLUFSEN_TRAILER_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_TRAILER_BIT_PAUSE_TIME + 0.5)\r
125\r
d155e9ab 126#define GRUNDIG_OR_NOKIA_PRE_PAUSE_LEN (uint8_t)(F_INTERRUPTS * GRUNDIG_OR_NOKIA_PRE_PAUSE_TIME + 0.5)\r
127#define GRUNDIG_OR_NOKIA_BIT_LEN (uint8_t)(F_INTERRUPTS * GRUNDIG_OR_NOKIA_BIT_TIME + 0.5)\r
128#define GRUNDIG_FRAME_REPETITION_LEN (uint16_t)(F_INTERRUPTS * GRUNDIG_FRAME_REPETITION_TIME + 0.5) // use uint16_t!\r
129#define NOKIA_FRAME_REPETITION_LEN (uint16_t)(F_INTERRUPTS * NOKIA_FRAME_REPETITION_TIME + 0.5) // use uint16_t!\r
5b437ff6 130\r
4225a882 131#define IRSND_FREQ_32_KHZ (uint8_t) ((F_CPU / 32000 / 2) - 1)\r
132#define IRSND_FREQ_36_KHZ (uint8_t) ((F_CPU / 36000 / 2) - 1)\r
133#define IRSND_FREQ_38_KHZ (uint8_t) ((F_CPU / 38000 / 2) - 1)\r
134#define IRSND_FREQ_40_KHZ (uint8_t) ((F_CPU / 40000 / 2) - 1)\r
135#define IRSND_FREQ_56_KHZ (uint8_t) ((F_CPU / 56000 / 2) - 1)\r
5481e9cd 136#define IRSND_FREQ_455_KHZ (uint8_t) ((F_CPU / 455000 / 2) - 1)\r
4225a882 137\r
138static volatile uint8_t irsnd_busy;\r
139static volatile uint8_t irsnd_protocol;\r
d155e9ab 140static volatile uint8_t irsnd_buffer[6];\r
4225a882 141static volatile uint8_t irsnd_is_on = FALSE;\r
142\r
143/*---------------------------------------------------------------------------------------------------------------------------------------------------\r
144 * Switch PWM on\r
145 * @details Switches PWM on with a narrow spike on all 3 channels -> leds glowing\r
146 *---------------------------------------------------------------------------------------------------------------------------------------------------\r
147 */\r
148static void\r
149irsnd_on (void)\r
150{\r
151 if (! irsnd_is_on)\r
152 {\r
153#ifndef DEBUG\r
154#if defined (__AVR_ATmega32__)\r
155 TCCR2 |= (1<<COM20)|(1<<WGM21); // = 0x42: toggle OC2A on compare match, clear Timer 2 at compare match OCR2A\r
156#else\r
157 TCCR2A |= (1<<COM2A0)|(1<<WGM21); // = 0x42: toggle OC2A on compare match, clear Timer 2 at compare match OCR2A\r
46dd89b7 158#endif // __AVR...\r
4225a882 159#endif // DEBUG\r
160 irsnd_is_on = TRUE;\r
161 }\r
162}\r
163\r
164/*---------------------------------------------------------------------------------------------------------------------------------------------------\r
165 * Switch PWM off\r
166 * @details Switches PWM off\r
167 *---------------------------------------------------------------------------------------------------------------------------------------------------\r
168 */\r
169static void\r
170irsnd_off (void)\r
171{\r
172 if (irsnd_is_on)\r
173 {\r
174#ifndef DEBUG\r
175#if defined (__AVR_ATmega32__)\r
176 TCCR2 &= ~(1<<COM20); // normal port operation, OC2A disconnected.\r
177#else\r
178 TCCR2A &= ~(1<<COM2A0); // normal port operation, OC2A disconnected.\r
46dd89b7 179#endif // __AVR...\r
4225a882 180 IRSND_PORT &= ~(1<<IRSND_BIT); // set IRSND_BIT to low\r
181#endif // DEBUG\r
182 irsnd_is_on = FALSE;\r
183 }\r
184}\r
185\r
186/*---------------------------------------------------------------------------------------------------------------------------------------------------\r
187 * Set PWM frequency\r
188 * @details sets pwm frequency\r
189 *---------------------------------------------------------------------------------------------------------------------------------------------------\r
190 */\r
191static void\r
192irsnd_set_freq (uint8_t freq)\r
193{\r
194#ifndef DEBUG\r
195#if defined (__AVR_ATmega32__)\r
196 OCR2 = freq;\r
197#else\r
198 OCR2A = freq;\r
46dd89b7 199#endif // __AVR...\r
4225a882 200#endif // DEBUG\r
201}\r
202\r
203/*---------------------------------------------------------------------------------------------------------------------------------------------------\r
204 * Initialize the PWM\r
205 * @details Configures 0CR0A, 0CR0B and 0CR2B as PWM channels\r
206 *---------------------------------------------------------------------------------------------------------------------------------------------------\r
207 */\r
208void\r
209irsnd_init (void)\r
210{\r
211#ifndef DEBUG\r
212 IRSND_PORT &= ~(1<<IRSND_BIT); // set IRSND_BIT to low\r
213 IRSND_DDR |= (1<<IRSND_BIT); // set IRSND_BIT to output\r
214\r
215#if defined (__AVR_ATmega32__)\r
216 TCCR2 = (1<<WGM21); // CTC mode\r
217 TCCR2 |= (1<<CS20); // 0x01, start Timer 2, no prescaling\r
218#else\r
219 TCCR2A = (1<<WGM21); // CTC mode\r
220 TCCR2B |= (1<<CS20); // 0x01, start Timer 2, no prescaling\r
46dd89b7 221#endif // __AVR... \r
4225a882 222\r
223 irsnd_set_freq (IRSND_FREQ_36_KHZ); // default frequency\r
224#endif // DEBUG\r
225}\r
226\r
227uint8_t\r
228irsnd_is_busy (void)\r
229{\r
230 return irsnd_busy;\r
231}\r
232\r
233static uint16_t\r
234bitsrevervse (uint16_t x, uint8_t len)\r
235{\r
236 uint16_t xx = 0;\r
237\r
238 while(len)\r
239 {\r
240 xx <<= 1;\r
241 if (x & 1)\r
242 {\r
243 xx |= 1;\r
244 }\r
245 x >>= 1;\r
246 len--;\r
247 }\r
248 return xx;\r
249}\r
250\r
251\r
252uint8_t\r
253irsnd_send_data (IRMP_DATA * irmp_data_p)\r
254{\r
255#if IRSND_SUPPORT_RECS80_PROTOCOL == 1\r
256 static uint8_t toggle_bit_recs80;\r
257#endif\r
258#if IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1\r
259 static uint8_t toggle_bit_recs80ext;\r
260#endif\r
261#if IRSND_SUPPORT_RC5_PROTOCOL == 1\r
262 static uint8_t toggle_bit_rc5;\r
263#endif\r
264 uint16_t address;\r
265 uint16_t command;\r
266\r
267 while (irsnd_busy)\r
268 {\r
269 ;\r
270 }\r
271\r
272 irsnd_protocol = irmp_data_p->protocol;\r
273\r
274 switch (irsnd_protocol)\r
275 {\r
276#if IRSND_SUPPORT_SIRCS_PROTOCOL == 1\r
277 case IRMP_SIRCS_PROTOCOL:\r
278 {\r
279 command = bitsrevervse (irmp_data_p->command, SIRCS_MINIMUM_DATA_LEN);\r
280\r
4225a882 281 irsnd_buffer[0] = (command & 0x0FF0) >> 4; // CCCCCCCC\r
282 irsnd_buffer[1] = (command & 0x000F) << 4; // CCCC0000\r
283 irsnd_busy = TRUE;\r
284 break;\r
285 }\r
286#endif\r
287#if IRSND_SUPPORT_NEC_PROTOCOL == 1\r
288 case IRMP_NEC_PROTOCOL:\r
46dd89b7 289 case IRMP_APPLE_PROTOCOL:\r
4225a882 290 {\r
291 address = bitsrevervse (irmp_data_p->address, NEC_ADDRESS_LEN);\r
292 command = bitsrevervse (irmp_data_p->command, NEC_COMMAND_LEN);\r
293\r
4225a882 294 irsnd_buffer[0] = (address & 0xFF00) >> 8; // AAAAAAAA\r
295 irsnd_buffer[1] = (address & 0x00FF); // AAAAAAAA\r
296 irsnd_buffer[2] = (command & 0xFF00) >> 8; // CCCCCCCC\r
46dd89b7 297\r
298 if (irsnd_protocol == IRMP_APPLE_PROTOCOL)\r
299 {\r
300 irsnd_protocol = IRMP_NEC_PROTOCOL; // APPLE protocol is NEC with fix bitmask instead of inverted command\r
301 irsnd_buffer[3] = 0x8B; // 10001011\r
302 }\r
303 else\r
304 {\r
305 irsnd_buffer[3] = ~((command & 0xFF00) >> 8); // cccccccc\r
306 }\r
307\r
4225a882 308 irsnd_busy = TRUE;\r
309 break;\r
310 }\r
311#endif\r
312#if IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1\r
313 case IRMP_SAMSUNG_PROTOCOL:\r
314 {\r
315 address = bitsrevervse (irmp_data_p->address, SAMSUNG_ADDRESS_LEN);\r
316 command = bitsrevervse (irmp_data_p->command, SAMSUNG_COMMAND_LEN);\r
317\r
4225a882 318 irsnd_buffer[0] = (address & 0xFF00) >> 8; // AAAAAAAA\r
319 irsnd_buffer[1] = (address & 0x00FF); // AAAAAAAA\r
320 irsnd_buffer[2] = (command & 0x00F0) | ((command & 0xF000) >> 12); // IIIICCCC\r
321 irsnd_buffer[3] = ((command & 0x0F00) >> 4) | ((~(command & 0xF000) >> 12) & 0x0F); // CCCCcccc\r
322 irsnd_buffer[4] = (~(command & 0x0F00) >> 4) & 0xF0; // cccc0000\r
323 irsnd_busy = TRUE;\r
324 break;\r
325 }\r
326 case IRMP_SAMSUNG32_PROTOCOL:\r
327 {\r
328 address = bitsrevervse (irmp_data_p->address, SAMSUNG_ADDRESS_LEN);\r
329 command = bitsrevervse (irmp_data_p->command, SAMSUNG32_COMMAND_LEN);\r
330\r
4225a882 331 irsnd_buffer[0] = (address & 0xFF00) >> 8; // AAAAAAAA\r
332 irsnd_buffer[1] = (address & 0x00FF); // AAAAAAAA\r
333 irsnd_buffer[2] = (command & 0xFF00) >> 8; // CCCCCCCC\r
334 irsnd_buffer[3] = (command & 0x00FF); // CCCCCCCC\r
335 irsnd_busy = TRUE;\r
336 break;\r
337 }\r
338#endif\r
339#if IRSND_SUPPORT_MATSUSHITA_PROTOCOL == 1\r
340 case IRMP_MATSUSHITA_PROTOCOL:\r
341 {\r
342 address = bitsrevervse (irmp_data_p->address, MATSUSHITA_ADDRESS_LEN);\r
343 command = bitsrevervse (irmp_data_p->command, MATSUSHITA_COMMAND_LEN);\r
344\r
4225a882 345 irsnd_buffer[0] = (command & 0x0FF0) >> 4; // CCCCCCCC\r
346 irsnd_buffer[1] = ((command & 0x000F) << 4) | ((address & 0x0F00) >> 8); // CCCCAAAA\r
347 irsnd_buffer[2] = (address & 0x00FF); // AAAAAAAA\r
348 irsnd_busy = TRUE;\r
349 break;\r
350 }\r
351#endif\r
352#if IRSND_SUPPORT_RECS80_PROTOCOL == 1\r
353 case IRMP_RECS80_PROTOCOL:\r
354 {\r
355 toggle_bit_recs80 = toggle_bit_recs80 ? 0x00 : 0x40;\r
356\r
4225a882 357 irsnd_buffer[0] = 0x80 | toggle_bit_recs80 | ((irmp_data_p->address & 0x0007) << 3) |\r
358 ((irmp_data_p->command & 0x0038) >> 3); // STAAACCC\r
359 irsnd_buffer[1] = (irmp_data_p->command & 0x07) << 5; // CCC00000\r
360 irsnd_busy = TRUE;\r
361 break;\r
362 }\r
363#endif\r
364#if IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1\r
365 case IRMP_RECS80EXT_PROTOCOL:\r
366 {\r
367 toggle_bit_recs80ext = toggle_bit_recs80ext ? 0x00 : 0x40;\r
368\r
4225a882 369 irsnd_buffer[0] = 0x80 | toggle_bit_recs80ext | ((irmp_data_p->address & 0x000F) << 2) |\r
370 ((irmp_data_p->command & 0x0030) >> 4); // STAAAACC\r
371 irsnd_buffer[1] = (irmp_data_p->command & 0x0F) << 4; // CCCC0000\r
372 irsnd_busy = TRUE;\r
373 break;\r
374 }\r
375#endif\r
376#if IRSND_SUPPORT_RC5_PROTOCOL == 1\r
377 case IRMP_RC5_PROTOCOL:\r
378 {\r
379 toggle_bit_rc5 = toggle_bit_rc5 ? 0x00 : 0x40;\r
380\r
4225a882 381 irsnd_buffer[0] = ((irmp_data_p->command & 0x40) ? 0x00 : 0x80) | toggle_bit_rc5 |\r
382 ((irmp_data_p->address & 0x001F) << 1) | ((irmp_data_p->command & 0x20) >> 5); // CTAAAAAC\r
383 irsnd_buffer[1] = (irmp_data_p->command & 0x1F) << 3; // CCCCC000\r
384 irsnd_busy = TRUE;\r
385 break;\r
386 }\r
387#endif\r
388#if IRSND_SUPPORT_DENON_PROTOCOL == 1\r
389 case IRMP_DENON_PROTOCOL:\r
390 {\r
d155e9ab 391 irsnd_buffer[0] = ((irmp_data_p->address & 0x1F) << 3) | ((irmp_data_p->command & 0x0380) >> 7); // AAAAACCC (1st frame)\r
392 irsnd_buffer[1] = (irmp_data_p->command & 0x7F) << 1; // CCCCCCC\r
393 irsnd_buffer[2] = ((irmp_data_p->address & 0x1F) << 3) | (((~irmp_data_p->command) & 0x0380) >> 7); // AAAAACCC (2nd frame)\r
394 irsnd_buffer[3] = (~(irmp_data_p->command) & 0x7F) << 1; // CCCCCCC\r
4225a882 395 irsnd_busy = TRUE;\r
396 break;\r
397 }\r
398#endif\r
399#if IRSND_SUPPORT_NUBERT_PROTOCOL == 1\r
400 case IRMP_NUBERT_PROTOCOL:\r
401 {\r
4225a882 402 irsnd_buffer[0] = irmp_data_p->command >> 2; // CCCCCCCC\r
403 irsnd_buffer[1] = (irmp_data_p->command & 0x0003) << 6; // CC000000\r
404 irsnd_busy = TRUE;\r
405 break;\r
406 }\r
5481e9cd 407#endif\r
408#if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1\r
409 case IRMP_BANG_OLUFSEN_PROTOCOL:\r
410 {\r
5481e9cd 411 irsnd_buffer[0] = irmp_data_p->command >> 11; // SXSCCCCC\r
412 irsnd_buffer[1] = irmp_data_p->command >> 3; // CCCCCCCC\r
413 irsnd_buffer[2] = (irmp_data_p->command & 0x0007) << 5; // CCC00000\r
414 irsnd_busy = TRUE;\r
415 break;\r
416 }\r
4225a882 417#endif\r
5b437ff6 418#if IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1\r
419 case IRMP_GRUNDIG_PROTOCOL:\r
420 {\r
421 command = bitsrevervse (irmp_data_p->command, GRUNDIG_COMMAND_LEN);\r
422\r
d155e9ab 423 irsnd_buffer[0] = 0xFF; // S1111111 (1st frame)\r
424 irsnd_buffer[1] = 0xC0; // 11\r
425 irsnd_buffer[2] = 0x80 | (command >> 2); // SCCCCCCC (2nd frame)\r
426 irsnd_buffer[3] = (command << 6) & 0xC0; // CC\r
427\r
428 irsnd_busy = TRUE;\r
429 break;\r
430 }\r
431#endif\r
432#if IRSND_SUPPORT_NOKIA_PROTOCOL == 1\r
433 case IRMP_NOKIA_PROTOCOL:\r
434 {\r
435 address = bitsrevervse (irmp_data_p->address, NOKIA_ADDRESS_LEN);\r
436 command = bitsrevervse (irmp_data_p->command, NOKIA_COMMAND_LEN);\r
437\r
438 irsnd_buffer[0] = 0xBF; // S0111111 (1st + 3rd frame)\r
439 irsnd_buffer[1] = 0xFF; // 11111111\r
440 irsnd_buffer[2] = 0x80; // 1\r
441 irsnd_buffer[3] = 0x80 | command >> 1; // SCCCCCCC (2nd frame)\r
442 irsnd_buffer[4] = (command << 7) | (address >> 1); // CAAAAAAA\r
443 irsnd_buffer[5] = (address << 7); // A\r
5b437ff6 444\r
445 irsnd_busy = TRUE;\r
446 break;\r
447 }\r
448#endif\r
4225a882 449 default:\r
450 {\r
451 break;\r
452 }\r
453 }\r
454\r
455 return irsnd_busy;\r
456}\r
457\r
458/*---------------------------------------------------------------------------------------------------------------------------------------------------\r
459 * ISR routine\r
460 * @details ISR routine, called 10000 times per second\r
461 *---------------------------------------------------------------------------------------------------------------------------------------------------\r
462 */\r
463uint8_t\r
464irsnd_ISR (void)\r
465{\r
466 static uint8_t current_bit = 0xFF;\r
467 static uint8_t pulse_counter;\r
468 static uint8_t pause_counter;\r
469 static uint8_t startbit_pulse_len;\r
470 static uint8_t startbit_pause_len;\r
471 static uint8_t pulse_1_len;\r
472 static uint8_t pause_1_len;\r
473 static uint8_t pulse_0_len;\r
474 static uint8_t pause_0_len;\r
475 static uint8_t has_stop_bit;\r
476 static uint8_t new_frame = TRUE;\r
477 static uint8_t complete_data_len;\r
5b437ff6 478 static uint8_t n_frames; // number of repetitions\r
479 static uint8_t frame_counter; // repetition counter\r
d155e9ab 480 static uint16_t repetition_pause_len; // pause before repetition, uint16_t!\r
4225a882 481 static uint16_t repetition_pause_counter; // pause before repetition, uint16_t!\r
5481e9cd 482#if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1\r
483 static uint8_t last_bit_value;\r
484#endif\r
485 static uint8_t pulse_len = 0xFF;\r
486 static uint8_t pause_len = 0xFF;\r
4225a882 487\r
488 if (irsnd_busy)\r
489 {\r
490 if (current_bit == 0xFF && new_frame) // start of transmission...\r
491 {\r
5481e9cd 492 if (frame_counter > 0)\r
4225a882 493 {\r
494 repetition_pause_counter++;\r
495\r
d155e9ab 496 if (repetition_pause_counter >= repetition_pause_len)\r
4225a882 497 {\r
498 repetition_pause_counter = 0;\r
499\r
500 if (irsnd_protocol == IRMP_DENON_PROTOCOL)\r
501 {\r
502 current_bit = 16;\r
503 complete_data_len = 2 * DENON_COMPLETE_DATA_LEN + 1;\r
504 }\r
5b437ff6 505 else if (irsnd_protocol == IRMP_GRUNDIG_PROTOCOL)\r
506 {\r
507 current_bit = 15;\r
508 complete_data_len = 16 + GRUNDIG_COMPLETE_DATA_LEN;\r
509 }\r
d155e9ab 510 else if (irsnd_protocol == IRMP_NOKIA_PROTOCOL)\r
511 {\r
512 if (frame_counter == 1)\r
513 {\r
514 current_bit = 23;\r
515 complete_data_len = 24 + NOKIA_COMPLETE_DATA_LEN;\r
516 }\r
517 else // if (frame_counter == 2)\r
518 {\r
519 current_bit = 0xFF;\r
520 complete_data_len = NOKIA_COMPLETE_DATA_LEN;\r
521 }\r
522 }\r
4225a882 523 }\r
524 else\r
525 {\r
526#ifdef DEBUG\r
527 if (irsnd_is_on)\r
528 {\r
529 putchar ('0');\r
530 }\r
531 else\r
532 {\r
533 putchar ('1');\r
534 }\r
535#endif\r
536 return irsnd_busy;\r
537 }\r
538 }\r
539 else\r
540 {\r
5481e9cd 541 pulse_counter = 0;\r
542 pause_counter = 0;\r
543\r
4225a882 544 switch (irsnd_protocol)\r
545 {\r
546#if IRSND_SUPPORT_SIRCS_PROTOCOL == 1\r
547 case IRMP_SIRCS_PROTOCOL:\r
548 {\r
d155e9ab 549 startbit_pulse_len = SIRCS_START_BIT_PULSE_LEN;\r
550 startbit_pause_len = SIRCS_START_BIT_PAUSE_LEN;\r
551 pulse_1_len = SIRCS_1_PULSE_LEN;\r
552 pause_1_len = SIRCS_PAUSE_LEN;\r
553 pulse_0_len = SIRCS_0_PULSE_LEN;\r
554 pause_0_len = SIRCS_PAUSE_LEN;\r
555 has_stop_bit = SIRCS_STOP_BIT;\r
556 complete_data_len = SIRCS_MINIMUM_DATA_LEN;\r
557 n_frames = SIRCS_FRAMES; // 3 frames\r
558 repetition_pause_len = SIRCS_FRAME_REPETITION_LEN; // 25ms pause\r
4225a882 559 irsnd_set_freq (IRSND_FREQ_40_KHZ);\r
560 break;\r
561 }\r
562#endif\r
563#if IRSND_SUPPORT_NEC_PROTOCOL == 1\r
564 case IRMP_NEC_PROTOCOL:\r
565 {\r
d155e9ab 566 startbit_pulse_len = NEC_START_BIT_PULSE_LEN;\r
567 startbit_pause_len = NEC_START_BIT_PAUSE_LEN;\r
568 pulse_1_len = NEC_PULSE_LEN;\r
569 pause_1_len = NEC_1_PAUSE_LEN;\r
570 pulse_0_len = NEC_PULSE_LEN;\r
571 pause_0_len = NEC_0_PAUSE_LEN;\r
572 has_stop_bit = NEC_STOP_BIT;\r
573 complete_data_len = NEC_COMPLETE_DATA_LEN;\r
574 n_frames = 1; // 1 frame\r
575 repetition_pause_len = 0;\r
4225a882 576 irsnd_set_freq (IRSND_FREQ_38_KHZ);\r
577 break;\r
578 }\r
579#endif\r
580#if IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1\r
581 case IRMP_SAMSUNG_PROTOCOL:\r
582 {\r
d155e9ab 583 startbit_pulse_len = SAMSUNG_START_BIT_PULSE_LEN;\r
584 startbit_pause_len = SAMSUNG_START_BIT_PAUSE_LEN;\r
585 pulse_1_len = SAMSUNG_PULSE_LEN;\r
586 pause_1_len = SAMSUNG_1_PAUSE_LEN;\r
587 pulse_0_len = SAMSUNG_PULSE_LEN;\r
588 pause_0_len = SAMSUNG_0_PAUSE_LEN;\r
589 has_stop_bit = SAMSUNG_STOP_BIT;\r
590 complete_data_len = SAMSUNG_COMPLETE_DATA_LEN;\r
591 n_frames = 1; // 1 frame\r
592 repetition_pause_len = 0;\r
4225a882 593 irsnd_set_freq (IRSND_FREQ_38_KHZ);\r
594 break;\r
595 }\r
596\r
597 case IRMP_SAMSUNG32_PROTOCOL:\r
598 {\r
d155e9ab 599 startbit_pulse_len = SAMSUNG_START_BIT_PULSE_LEN;\r
600 startbit_pause_len = SAMSUNG_START_BIT_PAUSE_LEN;\r
601 pulse_1_len = SAMSUNG_PULSE_LEN;\r
602 pause_1_len = SAMSUNG_1_PAUSE_LEN;\r
603 pulse_0_len = SAMSUNG_PULSE_LEN;\r
604 pause_0_len = SAMSUNG_0_PAUSE_LEN;\r
605 has_stop_bit = SAMSUNG_STOP_BIT;\r
606 complete_data_len = SAMSUNG32_COMPLETE_DATA_LEN;\r
607 n_frames = SAMSUNG32_FRAMES; // 2 frames\r
608 repetition_pause_len = SAMSUNG32_FRAME_REPETITION_LEN; // 47 ms pause\r
4225a882 609 irsnd_set_freq (IRSND_FREQ_38_KHZ);\r
610 break;\r
611 }\r
612#endif\r
613#if IRSND_SUPPORT_MATSUSHITA_PROTOCOL == 1\r
614 case IRMP_MATSUSHITA_PROTOCOL:\r
615 {\r
d155e9ab 616 startbit_pulse_len = MATSUSHITA_START_BIT_PULSE_LEN;\r
617 startbit_pause_len = MATSUSHITA_START_BIT_PAUSE_LEN;\r
618 pulse_1_len = MATSUSHITA_PULSE_LEN;\r
619 pause_1_len = MATSUSHITA_1_PAUSE_LEN;\r
620 pulse_0_len = MATSUSHITA_PULSE_LEN;\r
621 pause_0_len = MATSUSHITA_0_PAUSE_LEN;\r
622 has_stop_bit = MATSUSHITA_STOP_BIT;\r
623 complete_data_len = MATSUSHITA_COMPLETE_DATA_LEN;\r
624 n_frames = 1; // 1 frame\r
625 repetition_pause_len = 0;\r
4225a882 626 irsnd_set_freq (IRSND_FREQ_36_KHZ);\r
627 break;\r
628 }\r
629#endif\r
630#if IRSND_SUPPORT_RECS80_PROTOCOL == 1\r
631 case IRMP_RECS80_PROTOCOL:\r
632 {\r
d155e9ab 633 startbit_pulse_len = RECS80_START_BIT_PULSE_LEN;\r
634 startbit_pause_len = RECS80_START_BIT_PAUSE_LEN;\r
635 pulse_1_len = RECS80_PULSE_LEN;\r
636 pause_1_len = RECS80_1_PAUSE_LEN;\r
637 pulse_0_len = RECS80_PULSE_LEN;\r
638 pause_0_len = RECS80_0_PAUSE_LEN;\r
639 has_stop_bit = RECS80_STOP_BIT;\r
640 complete_data_len = RECS80_COMPLETE_DATA_LEN;\r
641 n_frames = 1; // 1 frame\r
642 repetition_pause_len = 0;\r
4225a882 643 irsnd_set_freq (IRSND_FREQ_38_KHZ);\r
644 break;\r
645 }\r
646#endif\r
647#if IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1\r
648 case IRMP_RECS80EXT_PROTOCOL:\r
649 {\r
d155e9ab 650 startbit_pulse_len = RECS80EXT_START_BIT_PULSE_LEN;\r
651 startbit_pause_len = RECS80EXT_START_BIT_PAUSE_LEN;\r
652 pulse_1_len = RECS80EXT_PULSE_LEN;\r
653 pause_1_len = RECS80EXT_1_PAUSE_LEN;\r
654 pulse_0_len = RECS80EXT_PULSE_LEN;\r
655 pause_0_len = RECS80EXT_0_PAUSE_LEN;\r
656 has_stop_bit = RECS80EXT_STOP_BIT;\r
657 complete_data_len = RECS80EXT_COMPLETE_DATA_LEN;\r
658 n_frames = 1; // 1 frame\r
659 repetition_pause_len = 0;\r
4225a882 660 irsnd_set_freq (IRSND_FREQ_38_KHZ);\r
661 break;\r
662 }\r
663#endif\r
664#if IRSND_SUPPORT_RC5_PROTOCOL == 1\r
665 case IRMP_RC5_PROTOCOL:\r
666 {\r
d155e9ab 667 startbit_pulse_len = RC5_BIT_LEN;\r
668 startbit_pause_len = RC5_BIT_LEN;\r
669 pulse_1_len = RC5_BIT_LEN;\r
670 pause_1_len = RC5_BIT_LEN;\r
671 pulse_0_len = RC5_BIT_LEN;\r
672 pause_0_len = RC5_BIT_LEN;\r
673 has_stop_bit = RC5_STOP_BIT;\r
674 complete_data_len = RC5_COMPLETE_DATA_LEN;\r
675 n_frames = 1; // 1 frame\r
676 repetition_pause_len = 0;\r
4225a882 677 irsnd_set_freq (IRSND_FREQ_36_KHZ);\r
678 break;\r
679 }\r
680#endif\r
681#if IRSND_SUPPORT_DENON_PROTOCOL == 1\r
682 case IRMP_DENON_PROTOCOL:\r
683 {\r
d155e9ab 684 startbit_pulse_len = 0x00;\r
685 startbit_pause_len = 0x00;\r
686 pulse_1_len = DENON_PULSE_LEN;\r
687 pause_1_len = DENON_1_PAUSE_LEN;\r
688 pulse_0_len = DENON_PULSE_LEN;\r
689 pause_0_len = DENON_0_PAUSE_LEN;\r
690 has_stop_bit = DENON_STOP_BIT;\r
691 complete_data_len = DENON_COMPLETE_DATA_LEN;\r
692 n_frames = DENON_FRAMES; // 2 frames, 2nd with inverted command\r
693 repetition_pause_len = DENON_FRAME_REPETITION_LEN; // 65 ms pause after 1st frame\r
4225a882 694 irsnd_set_freq (IRSND_FREQ_32_KHZ);\r
695 break;\r
696 }\r
697#endif\r
698#if IRSND_SUPPORT_NUBERT_PROTOCOL == 1\r
699 case IRMP_NUBERT_PROTOCOL:\r
700 {\r
d155e9ab 701 startbit_pulse_len = NUBERT_START_BIT_PULSE_LEN;\r
702 startbit_pause_len = NUBERT_START_BIT_PAUSE_LEN;\r
703 pulse_1_len = NUBERT_1_PULSE_LEN;\r
704 pause_1_len = NUBERT_1_PAUSE_LEN;\r
705 pulse_0_len = NUBERT_0_PULSE_LEN;\r
706 pause_0_len = NUBERT_0_PAUSE_LEN;\r
707 has_stop_bit = NUBERT_STOP_BIT;\r
708 complete_data_len = NUBERT_COMPLETE_DATA_LEN;\r
709 n_frames = NUBERT_FRAMES; // 2 frames\r
710 repetition_pause_len = NUBERT_FRAME_REPETITION_LEN; // 35 ms pause\r
4225a882 711 irsnd_set_freq (IRSND_FREQ_36_KHZ);\r
712 break;\r
713 }\r
5481e9cd 714#endif\r
715#if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1\r
716 case IRMP_BANG_OLUFSEN_PROTOCOL:\r
717 {\r
d155e9ab 718 startbit_pulse_len = BANG_OLUFSEN_START_BIT1_PULSE_LEN;\r
719 startbit_pause_len = BANG_OLUFSEN_START_BIT1_PAUSE_LEN;\r
720 pulse_1_len = BANG_OLUFSEN_PULSE_LEN;\r
721 pause_1_len = BANG_OLUFSEN_1_PAUSE_LEN;\r
722 pulse_0_len = BANG_OLUFSEN_PULSE_LEN;\r
723 pause_0_len = BANG_OLUFSEN_0_PAUSE_LEN;\r
724 has_stop_bit = BANG_OLUFSEN_STOP_BIT;\r
725 complete_data_len = BANG_OLUFSEN_COMPLETE_DATA_LEN;\r
726 n_frames = 1; // 1 frame\r
727 repetition_pause_len = 0;\r
728 last_bit_value = 0;\r
5481e9cd 729 irsnd_set_freq (IRSND_FREQ_455_KHZ);\r
730 break;\r
731 }\r
5b437ff6 732#endif\r
733#if IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1\r
734 case IRMP_GRUNDIG_PROTOCOL:\r
735 {\r
d155e9ab 736 startbit_pulse_len = GRUNDIG_OR_NOKIA_BIT_LEN;\r
737 startbit_pause_len = GRUNDIG_OR_NOKIA_PRE_PAUSE_LEN;\r
738 pulse_1_len = GRUNDIG_OR_NOKIA_BIT_LEN;\r
739 pause_1_len = GRUNDIG_OR_NOKIA_BIT_LEN;\r
740 pulse_0_len = GRUNDIG_OR_NOKIA_BIT_LEN;\r
741 pause_0_len = GRUNDIG_OR_NOKIA_BIT_LEN;\r
742 has_stop_bit = GRUNDIG_OR_NOKIA_STOP_BIT;\r
743 complete_data_len = GRUNDIG_COMPLETE_DATA_LEN;\r
744 n_frames = GRUNDIG_FRAMES; // 2 frames\r
745 repetition_pause_len = GRUNDIG_FRAME_REPETITION_LEN; // 20msec pause\r
746 irsnd_set_freq (IRSND_FREQ_38_KHZ);\r
747 break;\r
748 }\r
749#endif\r
750#if IRSND_SUPPORT_NOKIA_PROTOCOL == 1\r
751 case IRMP_NOKIA_PROTOCOL:\r
752 {\r
753 startbit_pulse_len = GRUNDIG_OR_NOKIA_BIT_LEN;\r
754 startbit_pause_len = GRUNDIG_OR_NOKIA_PRE_PAUSE_LEN;\r
755 pulse_1_len = GRUNDIG_OR_NOKIA_BIT_LEN;\r
756 pause_1_len = GRUNDIG_OR_NOKIA_BIT_LEN;\r
757 pulse_0_len = GRUNDIG_OR_NOKIA_BIT_LEN;\r
758 pause_0_len = GRUNDIG_OR_NOKIA_BIT_LEN;\r
759 has_stop_bit = GRUNDIG_OR_NOKIA_STOP_BIT;\r
760 complete_data_len = NOKIA_COMPLETE_DATA_LEN;\r
761 n_frames = NOKIA_FRAMES; // 2 frames\r
762 repetition_pause_len = NOKIA_FRAME_REPETITION_LEN; // 20msec pause\r
763 irsnd_set_freq (IRSND_FREQ_38_KHZ);\r
5b437ff6 764 break;\r
765 }\r
4225a882 766#endif\r
767 default:\r
768 {\r
769 irsnd_busy = FALSE;\r
770 break;\r
771 }\r
772 }\r
773 }\r
774 }\r
775\r
776 if (irsnd_busy)\r
777 {\r
778 new_frame = FALSE;\r
779 switch (irsnd_protocol)\r
780 {\r
781#if IRSND_SUPPORT_SIRCS_PROTOCOL == 1\r
782 case IRMP_SIRCS_PROTOCOL:\r
783#endif\r
784#if IRSND_SUPPORT_NEC_PROTOCOL == 1\r
785 case IRMP_NEC_PROTOCOL:\r
786#endif\r
787#if IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1\r
788 case IRMP_SAMSUNG_PROTOCOL:\r
789 case IRMP_SAMSUNG32_PROTOCOL:\r
790#endif\r
791#if IRSND_SUPPORT_MATSUSHITA_PROTOCOL == 1\r
792 case IRMP_MATSUSHITA_PROTOCOL:\r
793#endif\r
794#if IRSND_SUPPORT_RECS80_PROTOCOL == 1\r
795 case IRMP_RECS80_PROTOCOL:\r
796#endif\r
797#if IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1\r
798 case IRMP_RECS80EXT_PROTOCOL:\r
799#endif\r
800#if IRSND_SUPPORT_DENON_PROTOCOL == 1\r
801 case IRMP_DENON_PROTOCOL:\r
802#endif\r
803#if IRSND_SUPPORT_NUBERT_PROTOCOL == 1\r
804 case IRMP_NUBERT_PROTOCOL:\r
5481e9cd 805#endif\r
806#if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1\r
807 case IRMP_BANG_OLUFSEN_PROTOCOL:\r
4225a882 808#endif\r
809 {\r
5481e9cd 810 if (pulse_counter == 0)\r
4225a882 811 {\r
5481e9cd 812 if (current_bit == 0xFF) // send start bit\r
813 {\r
814 pulse_len = startbit_pulse_len;\r
815 pause_len = startbit_pause_len;\r
816 }\r
817 else if (current_bit < complete_data_len) // send n'th bit\r
4225a882 818 {\r
5481e9cd 819#if IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1\r
820 if (irsnd_protocol == IRMP_SAMSUNG_PROTOCOL)\r
4225a882 821 {\r
5481e9cd 822 if (current_bit < SAMSUNG_ADDRESS_LEN) // send address bits\r
823 {\r
824 pulse_len = SAMSUNG_PULSE_LEN;\r
825 pause_len = (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8)))) ?\r
826 SAMSUNG_1_PAUSE_LEN : SAMSUNG_0_PAUSE_LEN;\r
827 }\r
828 else if (current_bit == SAMSUNG_ADDRESS_LEN) // send SYNC bit (16th bit)\r
829 {\r
830 pulse_len = SAMSUNG_PULSE_LEN;\r
831 pause_len = SAMSUNG_START_BIT_PAUSE_LEN;\r
832 }\r
833 else if (current_bit < SAMSUNG_COMPLETE_DATA_LEN) // send n'th bit\r
834 {\r
835 uint8_t cur_bit = current_bit - 1; // sync skipped, offset = -1 !\r
836\r
837 pulse_len = SAMSUNG_PULSE_LEN;\r
838 pause_len = (irsnd_buffer[cur_bit / 8] & (1<<(7-(cur_bit % 8)))) ?\r
839 SAMSUNG_1_PAUSE_LEN : SAMSUNG_0_PAUSE_LEN;\r
840 }\r
4225a882 841 }\r
5481e9cd 842 else\r
843#endif\r
844\r
845#if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1\r
846 if (irsnd_protocol == IRMP_BANG_OLUFSEN_PROTOCOL)\r
4225a882 847 {\r
5481e9cd 848 if (current_bit == 0) // send 2nd start bit\r
849 {\r
850 pulse_len = BANG_OLUFSEN_START_BIT2_PULSE_LEN;\r
851 pause_len = BANG_OLUFSEN_START_BIT2_PAUSE_LEN;\r
852 }\r
853 else if (current_bit == 1) // send 3rd start bit\r
854 {\r
855 pulse_len = BANG_OLUFSEN_START_BIT3_PULSE_LEN;\r
856 pause_len = BANG_OLUFSEN_START_BIT3_PAUSE_LEN;\r
857 }\r
858 else if (current_bit == 2) // send 4th start bit\r
859 {\r
860 pulse_len = BANG_OLUFSEN_START_BIT2_PULSE_LEN;\r
861 pause_len = BANG_OLUFSEN_START_BIT2_PAUSE_LEN;\r
862 }\r
863 else if (current_bit == 19) // send trailer bit\r
864 {\r
865 pulse_len = BANG_OLUFSEN_PULSE_LEN;\r
866 pause_len = BANG_OLUFSEN_TRAILER_BIT_PAUSE_LEN;\r
867 }\r
868 else if (current_bit < BANG_OLUFSEN_COMPLETE_DATA_LEN) // send n'th bit\r
869 {\r
870 uint8_t cur_bit_value = (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8)))) ? 1 : 0;\r
871 pulse_len = BANG_OLUFSEN_PULSE_LEN;\r
872\r
873 if (cur_bit_value == last_bit_value)\r
874 {\r
875 pause_len = BANG_OLUFSEN_R_PAUSE_LEN;\r
876 }\r
877 else\r
878 {\r
879 pause_len = cur_bit_value ? BANG_OLUFSEN_1_PAUSE_LEN : BANG_OLUFSEN_0_PAUSE_LEN;\r
880 last_bit_value = cur_bit_value;\r
881 }\r
882 }\r
4225a882 883 }\r
5481e9cd 884 else\r
885#endif\r
886 if (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8))))\r
4225a882 887 {\r
5481e9cd 888 pulse_len = pulse_1_len;\r
889 pause_len = pause_1_len;\r
890 }\r
891 else\r
892 {\r
893 pulse_len = pulse_0_len;\r
894 pause_len = pause_0_len;\r
4225a882 895 }\r
896 }\r
5481e9cd 897 else if (has_stop_bit) // send stop bit\r
4225a882 898 {\r
899 pulse_len = pulse_0_len;\r
4225a882 900\r
5481e9cd 901 if (frame_counter < n_frames)\r
902 {\r
903 pause_len = pause_0_len;\r
904 }\r
905 else\r
906 {\r
907 pause_len = 255; // last frame: pause of 255\r
908 }\r
4225a882 909 }\r
910 }\r
911\r
912 if (pulse_counter < pulse_len)\r
913 {\r
914 if (pulse_counter == 0)\r
915 {\r
916 irsnd_on ();\r
917 }\r
918 pulse_counter++;\r
919 }\r
920 else if (pause_counter < pause_len)\r
921 {\r
922 if (pause_counter == 0)\r
923 {\r
924 irsnd_off ();\r
925 }\r
926 pause_counter++;\r
927 }\r
928 else\r
929 {\r
930 current_bit++;\r
931\r
932 if (current_bit >= complete_data_len + has_stop_bit)\r
933 {\r
934 current_bit = 0xFF;\r
5481e9cd 935 frame_counter++;\r
4225a882 936\r
5481e9cd 937 if (frame_counter == n_frames)\r
4225a882 938 {\r
939 irsnd_busy = FALSE;\r
5481e9cd 940 frame_counter = 0;\r
4225a882 941 }\r
942 new_frame = TRUE;\r
943 }\r
944\r
945 pulse_counter = 0;\r
946 pause_counter = 0;\r
947 }\r
948 break;\r
949 }\r
950#if IRSND_SUPPORT_RC5_PROTOCOL == 1\r
951 case IRMP_RC5_PROTOCOL:\r
952 {\r
953 uint8_t first_pulse;\r
954 uint8_t next_bit = FALSE;\r
955\r
956 if (current_bit == 0xFF) // 1 start bit\r
957 {\r
958 first_pulse = FALSE;\r
959 }\r
960 else // send n'th bit\r
961 {\r
962 first_pulse = (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8)))) ? FALSE : TRUE;\r
963 }\r
964\r
965 if (first_pulse)\r
966 {\r
967 if (pulse_counter < RC5_BIT_LEN)\r
968 {\r
969 if (pulse_counter == 0)\r
970 {\r
971 irsnd_on ();\r
972 }\r
973 pulse_counter++;\r
974 }\r
975 else if (pause_counter < RC5_BIT_LEN)\r
976 {\r
977 if (pause_counter == 0)\r
978 {\r
979 irsnd_off ();\r
980 }\r
981 pause_counter++;\r
982 }\r
983 else\r
984 {\r
985 next_bit = TRUE;\r
986 }\r
987 }\r
988 else\r
989 {\r
990 if (pause_counter < RC5_BIT_LEN)\r
991 {\r
992 if (pause_counter == 0)\r
993 {\r
994 irsnd_off ();\r
995 }\r
996 pause_counter++;\r
997 }\r
998 else if (pulse_counter < RC5_BIT_LEN)\r
999 {\r
1000 if (pulse_counter == 0)\r
1001 {\r
1002 irsnd_on ();\r
1003 }\r
1004 pulse_counter++;\r
1005 }\r
1006 else\r
1007 {\r
1008 next_bit = TRUE;\r
1009 }\r
1010 }\r
1011\r
1012 if (next_bit)\r
1013 {\r
1014 current_bit++;\r
1015\r
1016 if (current_bit >= RC5_COMPLETE_DATA_LEN)\r
1017 {\r
1018 current_bit = 0xFF;\r
1019 irsnd_busy = FALSE;\r
1020 new_frame = TRUE;\r
1021 irsnd_off ();\r
1022 }\r
1023\r
1024 pulse_counter = 0;\r
1025 pause_counter = 0;\r
1026 }\r
1027 break;\r
1028 }\r
1029#endif // IRSND_SUPPORT_RC5_PROTOCOL\r
5b437ff6 1030\r
d155e9ab 1031#if IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1 || IRSND_SUPPORT_NOKIA_PROTOCOL == 1\r
5b437ff6 1032 case IRMP_GRUNDIG_PROTOCOL:\r
d155e9ab 1033 case IRMP_NOKIA_PROTOCOL:\r
5b437ff6 1034 {\r
1035 uint8_t next_bit = FALSE;\r
1036\r
d155e9ab 1037 if (current_bit == 0xFF || // start bit of 1st frame\r
1038 (irsnd_protocol == IRMP_GRUNDIG_PROTOCOL && current_bit == 15) || // start bit of 2nd frame (Grundig)\r
1039 (irsnd_protocol == IRMP_NOKIA_PROTOCOL && (current_bit == 23 || current_bit == 47))) // start bit of 2nd/3rd frame (Nokia)\r
5b437ff6 1040 {\r
1041 if (pulse_counter == 0)\r
1042 {\r
1043 pulse_len = startbit_pulse_len;\r
1044 pause_len = startbit_pause_len;\r
1045 }\r
1046\r
1047 if (pulse_counter < pulse_len)\r
1048 {\r
1049 if (pulse_counter == 0)\r
1050 {\r
1051 irsnd_on ();\r
1052 }\r
1053 pulse_counter++;\r
1054 }\r
1055 else if (pause_counter < pause_len)\r
1056 {\r
1057 if (pause_counter == 0)\r
1058 {\r
1059 irsnd_off ();\r
1060 }\r
1061 pause_counter++;\r
1062 }\r
1063 else\r
1064 {\r
1065 current_bit++;\r
1066 pulse_counter = 0;\r
1067 pause_counter = 0;\r
1068 }\r
1069 }\r
1070 else // send n'th bit\r
1071 {\r
1072 uint8_t first_pulse;\r
1073\r
1074 first_pulse = (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8)))) ? TRUE : FALSE;\r
1075\r
1076 if (first_pulse)\r
1077 {\r
d155e9ab 1078 if (pulse_counter < GRUNDIG_OR_NOKIA_BIT_LEN)\r
5b437ff6 1079 {\r
1080 if (pulse_counter == 0)\r
1081 {\r
1082 irsnd_on ();\r
1083 }\r
1084 pulse_counter++;\r
1085 }\r
d155e9ab 1086 else if (pause_counter < GRUNDIG_OR_NOKIA_BIT_LEN)\r
5b437ff6 1087 {\r
1088 if (pause_counter == 0)\r
1089 {\r
1090 irsnd_off ();\r
1091 }\r
1092 pause_counter++;\r
1093 }\r
1094 else\r
1095 {\r
1096 next_bit = TRUE;\r
1097 }\r
1098 }\r
1099 else\r
1100 {\r
d155e9ab 1101 if (pause_counter < GRUNDIG_OR_NOKIA_BIT_LEN)\r
5b437ff6 1102 {\r
1103 if (pause_counter == 0)\r
1104 {\r
1105 irsnd_off ();\r
1106 }\r
1107 pause_counter++;\r
1108 }\r
d155e9ab 1109 else if (pulse_counter < GRUNDIG_OR_NOKIA_BIT_LEN)\r
5b437ff6 1110 {\r
1111 if (pulse_counter == 0)\r
1112 {\r
1113 irsnd_on ();\r
1114 }\r
1115 pulse_counter++;\r
1116 }\r
1117 else\r
1118 {\r
1119 next_bit = TRUE;\r
1120 }\r
1121 }\r
1122\r
1123 if (next_bit)\r
1124 {\r
1125 current_bit++;\r
1126\r
1127 if (current_bit >= complete_data_len)\r
1128 {\r
1129 current_bit = 0xFF;\r
1130 frame_counter++;\r
1131\r
1132 if (frame_counter == n_frames)\r
1133 {\r
1134 irsnd_busy = FALSE;\r
1135 frame_counter = 0;\r
1136 }\r
1137\r
1138 new_frame = TRUE;\r
1139 irsnd_off ();\r
1140 }\r
1141\r
1142 pulse_counter = 0;\r
1143 pause_counter = 0;\r
1144 }\r
1145 }\r
1146 break;\r
1147 }\r
d155e9ab 1148#endif // IRSND_SUPPORT_GRUNDIG_PROTOCOL || IRSND_SUPPORT_NOKIA_PROTOCOL\r
5b437ff6 1149\r
4225a882 1150 default:\r
1151 {\r
1152 irsnd_busy = FALSE;\r
1153 break;\r
1154 }\r
1155 }\r
1156 }\r
1157 }\r
1158\r
1159#ifdef DEBUG\r
1160 if (irsnd_is_on)\r
1161 {\r
1162 putchar ('0');\r
1163 }\r
1164 else\r
1165 {\r
1166 putchar ('1');\r
1167 }\r
1168#endif\r
1169\r
1170 return irsnd_busy;\r
1171}\r
1172\r
1173#ifdef DEBUG\r
1174\r
1175// main function - for unix/linux + windows only!\r
1176// AVR: see main.c!\r
1177// Compile it under linux with:\r
1178// cc irsnd.c -o irsnd\r
1179//\r
1180// usage: ./irsnd protocol hex-address hex-command >filename\r
1181\r
1182int\r
1183main (int argc, char ** argv)\r
1184{\r
1185 int idx;\r
1186 int cnt;\r
1187 int protocol;\r
1188 int address;\r
1189 int command;\r
1190 int repeat = 1;\r
1191 IRMP_DATA irmp_data;\r
1192\r
1193 if (argc != 4)\r
1194 {\r
1195 fprintf (stderr, "usage: %s protocol hex-address hex-command > filename\n", argv[0]);\r
1196 return 1;\r
1197 }\r
1198\r
1199 if (sscanf (argv[1], "%d", &protocol) == 1 &&\r
1200 sscanf (argv[2], "%x", &address) == 1 &&\r
1201 sscanf (argv[3], "%x", &command) == 1)\r
1202 {\r
1203 irmp_data.protocol = protocol;\r
1204 irmp_data.address = address;\r
1205 irmp_data.command = command;\r
1206\r
1207 irsnd_init ();\r
1208\r
1209 for (cnt = 0; cnt < repeat; cnt++)\r
1210 {\r
1211 (void) irsnd_send_data (&irmp_data);\r
1212\r
1213 for (idx = 0; idx < 3000; idx++)\r
1214 {\r
1215 irsnd_ISR ();\r
1216 }\r
1217 }\r
1218\r
1219 putchar ('\n');\r
1220 }\r
1221 else\r
1222 {\r
1223 fprintf (stderr, "%s: wrong arguments\n", argv[0]);\r
1224 return 1;\r
1225 }\r
1226 return 0;\r
1227}\r
1228\r
1229#endif // DEBUG\r