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