Added lirc.
[irreco.git] / lirc-0.8.4a / daemons / transmit.c
blobae49470199b7477d7cd979b8c217b1e52abf4362
1 /* $Id: transmit.c,v 5.28 2008/05/11 13:29:47 lirc Exp $ */
3 /****************************************************************************
4 ** transmit.c **************************************************************
5 ****************************************************************************
7 * functions that prepare IR codes for transmitting
8 *
9 * Copyright (C) 1999-2004 Christoph Bartelmus <lirc@bartelmus.de>
13 #ifdef HAVE_CONFIG_H
14 # include <config.h>
15 #endif
17 /* if the gap is lower than this value, we will concatenate the
18 signals and send the signal chain at a single blow */
19 #define LIRCD_EXACT_GAP_THRESHOLD 10000
21 #include "lircd.h"
22 #include "transmit.h"
24 extern struct ir_remote *repeat_remote;
25 struct sbuf send_buffer;
27 static void send_signals(lirc_t *signals, int n);
29 inline void set_bit(ir_code *code,int bit,int data)
31 (*code)&=~((((ir_code) 1)<<bit));
32 (*code)|=((ir_code) (data ? 1:0)<<bit);
36 sending stuff
39 void init_send_buffer(void)
41 memset(&send_buffer,0,sizeof(send_buffer));
44 inline void clear_send_buffer(void)
46 LOGPRINTF(3, "clearing transmit buffer");
47 send_buffer.wptr=0;
48 send_buffer.too_long=0;
49 send_buffer.is_biphase=0;
50 send_buffer.pendingp=0;
51 send_buffer.pendings=0;
52 send_buffer.sum=0;
55 inline void add_send_buffer(lirc_t data)
57 if(send_buffer.wptr<WBUF_SIZE)
59 LOGPRINTF(3, "adding to transmit buffer: %u", data);
60 send_buffer.sum+=data;
61 send_buffer._data[send_buffer.wptr]=data;
62 send_buffer.wptr++;
64 else
66 send_buffer.too_long=1;
70 inline void send_pulse(lirc_t data)
72 if(send_buffer.pendingp>0)
74 send_buffer.pendingp+=data;
76 else
78 if(send_buffer.pendings>0)
80 add_send_buffer(send_buffer.pendings);
81 send_buffer.pendings=0;
83 send_buffer.pendingp=data;
87 inline void send_space(lirc_t data)
89 if(send_buffer.wptr==0 && send_buffer.pendingp==0)
91 LOGPRINTF(1,"first signal is a space!");
92 return;
94 if(send_buffer.pendings>0)
96 send_buffer.pendings+=data;
98 else
100 if(send_buffer.pendingp>0)
102 add_send_buffer(send_buffer.pendingp);
103 send_buffer.pendingp=0;
105 send_buffer.pendings=data;
109 static inline int bad_send_buffer(void)
111 if(send_buffer.too_long!=0) return(1);
112 if(send_buffer.wptr==WBUF_SIZE && send_buffer.pendingp>0)
114 return(1);
116 return(0);
119 static int check_send_buffer(void)
121 int i;
123 if (send_buffer.wptr == 0)
125 LOGPRINTF(1, "nothing to send");
126 return(0);
128 for (i = 0; i < send_buffer.wptr; i++)
130 if(send_buffer.data[i] == 0)
132 if(i%2)
134 LOGPRINTF(1, "invalid space: %d", i);
136 else
138 LOGPRINTF(1, "invalid pulse: %d", i);
140 return 0;
144 return 1;
147 static inline void flush_send_buffer(void)
149 if(send_buffer.pendingp>0)
151 add_send_buffer(send_buffer.pendingp);
152 send_buffer.pendingp=0;
154 if(send_buffer.pendings>0)
156 add_send_buffer(send_buffer.pendings);
157 send_buffer.pendings=0;
161 static inline void sync_send_buffer(void)
163 if(send_buffer.pendingp>0)
165 add_send_buffer(send_buffer.pendingp);
166 send_buffer.pendingp=0;
168 if(send_buffer.wptr>0 && send_buffer.wptr%2==0) send_buffer.wptr--;
171 inline void send_header(struct ir_remote *remote)
173 if(has_header(remote))
175 send_pulse(remote->phead);
176 send_space(remote->shead);
180 inline void send_foot(struct ir_remote *remote)
182 if(has_foot(remote))
184 send_space(remote->sfoot);
185 send_pulse(remote->pfoot);
189 inline void send_lead(struct ir_remote *remote)
191 if(remote->plead!=0)
193 send_pulse(remote->plead);
197 inline void send_trail(struct ir_remote *remote)
199 if(remote->ptrail!=0)
201 send_pulse(remote->ptrail);
205 inline void send_data(struct ir_remote *remote,ir_code data,int bits,int done)
207 int i;
208 int all_bits = bit_count(remote);
209 ir_code mask;
210 if(is_rcmm(remote))
212 data=reverse(data,bits);
213 mask=1<<(all_bits-1-done);
214 if(bits%2 || done%2)
216 logprintf(LOG_ERR,"invalid bit number.");
217 return;
219 for(i=0;i<bits;i+=2,mask>>=2)
221 switch(data&3)
223 case 0:
224 send_pulse(remote->pzero);
225 send_space(remote->szero);
226 break;
227 /* 2 and 1 swapped due to reverse() */
228 case 2:
229 send_pulse(remote->pone);
230 send_space(remote->sone);
231 break;
232 case 1:
233 send_pulse(remote->ptwo);
234 send_space(remote->stwo);
235 break;
236 case 3:
237 send_pulse(remote->pthree);
238 send_space(remote->sthree);
239 break;
241 data=data>>2;
243 return;
246 data=reverse(data,bits);
247 mask=((ir_code) 1)<<(all_bits-1-done);
248 for(i=0;i<bits;i++,mask>>=1)
250 if(has_toggle_bit_mask(remote) && mask&remote->toggle_bit_mask)
252 data &= ~((ir_code) 1);
253 if(remote->toggle_bit_mask_state&mask)
255 data |= (ir_code) 1;
259 if(has_toggle_mask(remote) &&
260 mask&remote->toggle_mask &&
261 remote->toggle_mask_state%2)
263 data ^= 1;
265 if(data&1)
267 if(is_biphase(remote))
270 if(mask&remote->rc6_mask)
272 send_space(2*remote->sone);
273 send_pulse(2*remote->pone);
275 else
277 send_space(remote->sone);
278 send_pulse(remote->pone);
281 else if(is_space_first(remote))
283 send_space(remote->sone);
284 send_pulse(remote->pone);
286 else
288 send_pulse(remote->pone);
289 send_space(remote->sone);
292 else
294 if(mask&remote->rc6_mask)
296 send_pulse(2*remote->pzero);
297 send_space(2*remote->szero);
299 else if(is_space_first(remote))
301 send_space(remote->szero);
302 send_pulse(remote->pzero);
304 else
306 send_pulse(remote->pzero);
307 send_space(remote->szero);
310 data=data>>1;
314 inline void send_pre(struct ir_remote *remote)
316 if(has_pre(remote))
318 send_data(remote,remote->pre_data,remote->pre_data_bits,0);
319 if(remote->pre_p>0 && remote->pre_s>0)
321 send_pulse(remote->pre_p);
322 send_space(remote->pre_s);
327 inline void send_post(struct ir_remote *remote)
329 if(has_post(remote))
331 if(remote->post_p>0 && remote->post_s>0)
333 send_pulse(remote->post_p);
334 send_space(remote->post_s);
336 send_data(remote,remote->post_data,remote->post_data_bits,
337 remote->pre_data_bits+remote->bits);
341 inline void send_repeat(struct ir_remote *remote)
343 send_lead(remote);
344 send_pulse(remote->prepeat);
345 send_space(remote->srepeat);
346 send_trail(remote);
349 inline void send_code(struct ir_remote *remote,ir_code code, int repeat)
351 if(!repeat || !(remote->flags&NO_HEAD_REP))
352 send_header(remote);
353 send_lead(remote);
354 send_pre(remote);
355 send_data(remote,code,remote->bits,remote->pre_data_bits);
356 send_post(remote);
357 send_trail(remote);
358 if(!repeat || !(remote->flags&NO_FOOT_REP))
359 send_foot(remote);
361 if(!repeat &&
362 remote->flags&NO_HEAD_REP &&
363 remote->flags&CONST_LENGTH)
365 send_buffer.sum-=remote->phead+remote->shead;
369 static void send_signals(lirc_t *signals, int n)
371 int i;
373 for(i=0; i<n; i++)
375 add_send_buffer(signals[i]);
379 int init_send(struct ir_remote *remote,struct ir_ncode *code)
381 int i, repeat=0;
383 if(is_grundig(remote) ||
384 is_goldstar(remote) || is_serial(remote) || is_bo(remote))
386 logprintf(LOG_ERR,"sorry, can't send this protocol yet");
387 return(0);
389 clear_send_buffer();
390 if(is_biphase(remote))
392 send_buffer.is_biphase=1;
394 if(repeat_remote==NULL)
396 remote->repeat_countdown=remote->min_repeat;
398 else
400 repeat = 1;
403 init_send_loop:
404 if(repeat && has_repeat(remote))
406 if(remote->flags&REPEAT_HEADER && has_header(remote))
408 send_header(remote);
410 send_repeat(remote);
412 else
414 if(!is_raw(remote))
416 ir_code next_code;
418 if(code->transmit_state == NULL)
420 next_code = code->code;
422 else
424 next_code = code->transmit_state->code;
426 send_code(remote, next_code, repeat);
427 if(has_toggle_mask(remote))
429 remote->toggle_mask_state++;
430 if(remote->toggle_mask_state==4)
432 remote->toggle_mask_state=2;
435 send_buffer.data=send_buffer._data;
437 else
439 if(code->signals==NULL)
441 logprintf(LOG_ERR, "no signals for raw send");
442 return 0;
444 if(send_buffer.wptr>0)
446 send_signals(code->signals, code->length);
448 else
450 send_buffer.data=code->signals;
451 send_buffer.wptr=code->length;
452 for(i=0; i<code->length; i++)
454 send_buffer.sum+=code->signals[i];
459 sync_send_buffer();
460 if(bad_send_buffer())
462 logprintf(LOG_ERR,"buffer too small");
463 return(0);
465 if(has_repeat_gap(remote) && repeat && has_repeat(remote))
467 remote->min_remaining_gap=remote->repeat_gap;
468 remote->max_remaining_gap=remote->repeat_gap;
470 else if(is_const(remote))
472 if(min_gap(remote)>send_buffer.sum)
474 remote->min_remaining_gap=min_gap(remote)-send_buffer.sum;
475 remote->max_remaining_gap=max_gap(remote)-send_buffer.sum;
477 else
479 logprintf(LOG_ERR,"too short gap: %u",remote->gap);
480 remote->min_remaining_gap=min_gap(remote);
481 remote->max_remaining_gap=max_gap(remote);
482 return(0);
485 else
487 remote->min_remaining_gap=min_gap(remote);
488 remote->max_remaining_gap=max_gap(remote);
490 /* update transmit state */
491 if(code->next != NULL)
493 if(code->transmit_state == NULL)
495 code->transmit_state = code->next;
497 else
499 code->transmit_state = code->transmit_state->next;
502 if((remote->repeat_countdown>0 || code->transmit_state != NULL) &&
503 remote->min_remaining_gap<LIRCD_EXACT_GAP_THRESHOLD)
505 if(send_buffer.data!=send_buffer._data)
507 lirc_t *signals;
508 int n;
510 LOGPRINTF(1, "unrolling raw signal optimisation");
511 signals=send_buffer.data;
512 n=send_buffer.wptr;
513 send_buffer.data=send_buffer._data;
514 send_buffer.wptr=0;
516 send_signals(signals, n);
518 LOGPRINTF(1, "concatenating low gap signals");
519 if(code->next == NULL || code->transmit_state == NULL)
521 remote->repeat_countdown--;
523 send_space(remote->min_remaining_gap);
524 flush_send_buffer();
525 send_buffer.sum=0;
527 repeat = 1;
528 goto init_send_loop;
530 LOGPRINTF(3, "transmit buffer ready");
531 if(!check_send_buffer())
533 logprintf(LOG_ERR, "invalid send buffer");
534 logprintf(LOG_ERR,
535 "this remote configuration cannot be used "
536 "to transmit");
537 return 0;
539 return 1;