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
9 * Copyright (C) 1999-2004 Christoph Bartelmus <lirc@bartelmus.de>
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
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
);
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");
48 send_buffer
.too_long
=0;
49 send_buffer
.is_biphase
=0;
50 send_buffer
.pendingp
=0;
51 send_buffer
.pendings
=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
;
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
;
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!");
94 if(send_buffer
.pendings
>0)
96 send_buffer
.pendings
+=data
;
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)
119 static int check_send_buffer(void)
123 if (send_buffer
.wptr
== 0)
125 LOGPRINTF(1, "nothing to send");
128 for (i
= 0; i
< send_buffer
.wptr
; i
++)
130 if(send_buffer
.data
[i
] == 0)
134 LOGPRINTF(1, "invalid space: %d", i
);
138 LOGPRINTF(1, "invalid pulse: %d", i
);
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
)
184 send_space(remote
->sfoot
);
185 send_pulse(remote
->pfoot
);
189 inline void send_lead(struct ir_remote
*remote
)
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
)
208 int all_bits
= bit_count(remote
);
212 data
=reverse(data
,bits
);
213 mask
=1<<(all_bits
-1-done
);
216 logprintf(LOG_ERR
,"invalid bit number.");
219 for(i
=0;i
<bits
;i
+=2,mask
>>=2)
224 send_pulse(remote
->pzero
);
225 send_space(remote
->szero
);
227 /* 2 and 1 swapped due to reverse() */
229 send_pulse(remote
->pone
);
230 send_space(remote
->sone
);
233 send_pulse(remote
->ptwo
);
234 send_space(remote
->stwo
);
237 send_pulse(remote
->pthree
);
238 send_space(remote
->sthree
);
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
)
259 if(has_toggle_mask(remote
) &&
260 mask
&remote
->toggle_mask
&&
261 remote
->toggle_mask_state
%2)
267 if(is_biphase(remote
))
270 if(mask
&remote
->rc6_mask
)
272 send_space(2*remote
->sone
);
273 send_pulse(2*remote
->pone
);
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
);
288 send_pulse(remote
->pone
);
289 send_space(remote
->sone
);
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
);
306 send_pulse(remote
->pzero
);
307 send_space(remote
->szero
);
314 inline void send_pre(struct ir_remote
*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
)
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
)
344 send_pulse(remote
->prepeat
);
345 send_space(remote
->srepeat
);
349 inline void send_code(struct ir_remote
*remote
,ir_code code
, int repeat
)
351 if(!repeat
|| !(remote
->flags
&NO_HEAD_REP
))
355 send_data(remote
,code
,remote
->bits
,remote
->pre_data_bits
);
358 if(!repeat
|| !(remote
->flags
&NO_FOOT_REP
))
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
)
375 add_send_buffer(signals
[i
]);
379 int init_send(struct ir_remote
*remote
,struct ir_ncode
*code
)
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");
390 if(is_biphase(remote
))
392 send_buffer
.is_biphase
=1;
394 if(repeat_remote
==NULL
)
396 remote
->repeat_countdown
=remote
->min_repeat
;
404 if(repeat
&& has_repeat(remote
))
406 if(remote
->flags
&REPEAT_HEADER
&& has_header(remote
))
418 if(code
->transmit_state
== NULL
)
420 next_code
= code
->code
;
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
;
439 if(code
->signals
==NULL
)
441 logprintf(LOG_ERR
, "no signals for raw send");
444 if(send_buffer
.wptr
>0)
446 send_signals(code
->signals
, code
->length
);
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
];
460 if(bad_send_buffer())
462 logprintf(LOG_ERR
,"buffer too small");
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
;
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
);
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
;
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
)
510 LOGPRINTF(1, "unrolling raw signal optimisation");
511 signals
=send_buffer
.data
;
513 send_buffer
.data
=send_buffer
._data
;
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
);
530 LOGPRINTF(3, "transmit buffer ready");
531 if(!check_send_buffer())
533 logprintf(LOG_ERR
, "invalid send buffer");
535 "this remote configuration cannot be used "