1 /*****************************************************************************
2 ** hw_irlink.c **************************************************************
3 *****************************************************************************
4 * Routines for the IRLink VS Infrared receiver
6 * Copyright (C) 2007 Maxim Muratov <mumg at mail.ru>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Library General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
35 #include <sys/types.h>
36 #include <sys/ioctl.h>
44 #include "ir_remote.h"
46 #include "hw_irlink.h"
48 struct hardware hw_irlink
= {
49 LIRC_DRIVER_DEVICE
, /* Default device */
51 LIRC_CAN_REC_MODE2
, /* Features */
53 LIRC_MODE_MODE2
, /* rec_mode */
55 irlink_init
, /* init_func */
56 NULL
, /* config_func */
57 irlink_deinit
, /* deinit_func */
59 irlink_rec
, /* rec_func */
60 receive_decode
, /* decode_func */
61 NULL
, /* ioctl_func */
62 irlink_readdata
, /* readdata */
73 #define IS_IRLINK_LONG_PULSE(code) (code == 0xFF)
74 #define IS_IRLINK_LONG_PAUSE(code) (code == 0xFE)
76 #define IS_IRLINK_PULSE(code) (code & 0x01)
78 #define IS_IRLINK_TIMESCALE_3600(code) ((code & 0x80) > 0)
79 #define IS_IRLINK_TIMESCALE_14400(code) ((code & 0x80) == 0)
81 #define IRLINK_DETECT_CMD 0x81
83 #define IRLINK_PERIOD(value,timescale) \
84 (((1000000 * ((unsigned int)value))/timescale)&PULSE_MASK)
86 static int is_long_pause
= 0;
87 static int is_long_pulse
= 0;
88 static struct timeval last_time
= {0};
89 static unsigned char pulse
= 1;
90 static lirc_t last_code
= 0;
92 static int irlink_close(const int port
)
104 static int irlink_open(const char * portName
)
107 if(!tty_create_lock((char*)portName
))
109 logprintf(LOG_ERR
,"could not create lock files");
112 if((port
=open(portName
,O_RDWR
| O_NOCTTY
| O_NDELAY
))<0)
114 logprintf(LOG_ERR
,"could not open %s",hw
.device
);
118 if(tty_reset(port
) < 0 ||
119 tty_setbaud(port
, 115200) < 0 ||
120 tty_setcsize(port
, 8) < 0 ||
121 tty_setrtscts(port
, 0) < 0 )
129 static int irlink_read(const int port
,
130 unsigned char * buffer
,
137 return read(port
, buffer
, bufferSize
);
141 static int irlink_write(const int port
,
142 unsigned char * buffer
,
149 return write(port
, buffer
, bufferSize
);
152 static void irlink_read_flush(const int port
)
163 if(select(port
+ 1 , &fds
, 0 , 0 , &tm
) > 0)
165 if (read(port
, &data
, sizeof(data
)) <= 0)
178 static int irlink_detect(const int port
)
180 unsigned char detect_cmd
[] = { IRLINK_DETECT_CMD
};
185 irlink_read_flush(port
);
186 if ( irlink_write(port
,
188 sizeof(detect_cmd
)) == sizeof(detect_cmd
))
190 unsigned char detect_response
= 0;
191 if ( waitfordata(500000) &&
194 sizeof(detect_response
) ) == sizeof(detect_response
))
196 if (detect_response
== IRLINK_DETECT_CMD
)
207 char *irlink_rec(struct ir_remote
*remotes
)
209 if(!clear_rec_buffer()) return(NULL
);
210 return(decode_all(remotes
));
213 lirc_t
irlink_readdata(lirc_t timeout
)
216 unsigned char rd_value
= 0;
217 struct timeval start_time
= {0};
218 gettimeofday(&start_time
, NULL
);
219 lirc_t time_delta
= 0;
228 if (timeout
< time_delta
)
230 logprintf (LOG_ERR
, "timeout < time_delta");
233 if (!waitfordata(timeout
- time_delta
))
237 if ( irlink_read(hw
.fd
,
239 sizeof(rd_value
)) == sizeof(rd_value
) )
241 if ( IS_IRLINK_LONG_PULSE(rd_value
)||
242 IS_IRLINK_LONG_PAUSE(rd_value
))
244 struct timeval diff_time
= {0};
245 is_long_pulse
= IS_IRLINK_LONG_PULSE(rd_value
);
246 is_long_pause
= IS_IRLINK_LONG_PAUSE(rd_value
);
247 gettimeofday(&last_time
, NULL
);
251 time_delta
= diff_time
.tv_sec
* 1000000 +
257 lirc_t
* code_ptr
= &data
;
258 if ( is_long_pulse
!= 0 ||
261 struct timeval curr_time
;
262 struct timeval diff_time
;
263 gettimeofday(&curr_time
, NULL
);
268 if (diff_time
.tv_sec
>= 16)
274 data
= diff_time
.tv_sec
*
290 code_ptr
= &last_code
;
292 if(IS_IRLINK_TIMESCALE_3600(rd_value
))
294 rd_value
= (rd_value
& 0x7F) >> 1;
295 *code_ptr
= IRLINK_PERIOD(rd_value
,3600);
297 else if (IS_IRLINK_TIMESCALE_14400(rd_value
))
299 rd_value
= (rd_value
& 0x7F) >> 1;
300 *code_ptr
= IRLINK_PERIOD(rd_value
,14400);
304 *code_ptr
&= ~PULSE_BIT
;
308 *code_ptr
|= PULSE_BIT
;
316 logprintf(LOG_ERR
, "error reading from %s", hw
.device
);
317 logperror(LOG_ERR
, NULL
);
324 int irlink_init(void)
326 hw
.fd
= irlink_open(hw
.device
);
329 logprintf (LOG_ERR
, "Could not open the '%s' device",
334 if ( irlink_detect(hw
.fd
) == 0 )
340 logprintf (LOG_ERR
, "Failed to detect IRLink "
349 int irlink_deinit (void)