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