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