Added lirc.
[irreco.git] / lirc-0.8.4a / daemons / hw_tira.c
blob5452c51043a7fda60657d48899df082dc2a19208
1 /* $Id: hw_tira.c,v 5.6 2007/07/29 18:20:09 lirc Exp $ */
2 /*****************************************************************************
3 ** hw_tira.c ****************************************************************
4 *****************************************************************************
5 * Routines for the HomeElectronics TIRA-2 USB dongle.
7 * Serial protocol described at:
8 * http://www.home-electro.com/Download/Protocol2.pdf
10 * Copyright (C) 2003 Gregory McLean <gregm@gxsnmp.org>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Library General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <fcntl.h>
35 #include <unistd.h>
36 #include <limits.h>
37 #include <signal.h>
38 #include <sys/stat.h>
39 #include <sys/types.h>
40 #include <sys/ioctl.h>
41 #include <errno.h>
42 #include <termios.h>
44 #include "hardware.h"
45 #include "receive.h"
46 #include "serial.h"
47 #include "ir_remote.h"
48 #include "lircd.h"
49 #include "hw_tira.h"
51 static struct timeval start,end,last;
52 static unsigned char b[6];
53 static ir_code code;
55 #define CODE_LENGTH 64
56 struct hardware hw_tira = {
57 "/dev/ttyUSB0", /* Default device */
58 -1, /* fd */
59 LIRC_CAN_REC_LIRCCODE, /* Features */
60 0, /* send_mode */
61 LIRC_MODE_LIRCCODE, /* rec_mode */
62 CODE_LENGTH, /* code_length */
63 tira_init, /* init_func */
64 NULL, /* config_func */
65 tira_deinit, /* deinit_func */
66 NULL, /* send_func */
67 tira_rec, /* rec_func */
68 tira_decode, /* decode_func */
69 NULL, /* ioctl_func */
70 NULL, /* readdata */
71 "tira"
74 int tira_setup(void);
76 int tira_decode (struct ir_remote *remote, ir_code *prep, ir_code *codep,
77 ir_code *postp, int *repeat_flagp,
78 lirc_t *min_remaining_gapp,
79 lirc_t *max_remaining_gapp)
81 if(!map_code(remote, prep, codep, postp,
82 0, 0, CODE_LENGTH, code, 0, 0))
84 return 0;
87 map_gap(remote, &start, &last, 0, repeat_flagp,
88 min_remaining_gapp, max_remaining_gapp);
90 return 1;
93 int tira_setup(void)
95 char response[64+1];
96 int i;
97 int ptr;
99 /* Clear the port of any random data */
100 while (read(hw.fd, &ptr, 1) >= 0) ;
102 /* Start off with the IP command. This was initially used to
103 switch to timing mode on the Tira-1. The Tira-2 also
104 supports this mode, however it does not switch the Tira-2
105 into timing mode.
107 if (write (hw.fd, "IP", 2) != 2)
109 logprintf(LOG_ERR, "failed writing to device");
110 return 0;
112 /* Wait till the chars are written, should use tcdrain but
113 that don't seem to work... *shrug*
115 usleep (2 * (100 * 1000));
116 i = read (hw.fd, response, 3);
117 if (strncmp(response, "OIP", 3) == 0)
119 read (hw.fd, &ptr, 1); /* read the calibration value */
120 read (hw.fd, &ptr, 1); /* read the version word */
121 /* Bits 4:7 in the version word set to one indicates a
122 Tira-2 */
123 if (ptr & 0xF0)
125 logprintf(LOG_INFO, "Tira-2 detected");
126 /* Lets get the firmware version */
127 write (hw.fd, "IV", 2);
128 usleep (2 * (100 * 1000));
129 memset (response, 0, sizeof(response));
130 i = read (hw.fd, response, sizeof(response)-1);
131 logprintf(LOG_INFO, "firmware version %s", response);
133 else
135 logprintf(LOG_INFO, "Ira/Tira-1 detected");
137 /* According to the docs we can do some bit work here
138 and figure out what the device supports from the
139 version word retrived.
141 At this point we have a Device of some sort. Lets
142 kick it into "Six bytes" mode.
144 if (write(hw.fd, "IR", 2 ) != 2)
146 logprintf(LOG_ERR, "failed switching device "
147 "into six byte mod");
148 return 0;
150 /* wait for the chars to be written */
151 usleep (2 * (100 * 1000));
153 i = read (hw.fd, response, 2);
154 if (i != 2)
156 logprintf(LOG_ERR, "failed reading response "
157 "to six byte mode command");
158 return 0;
160 else
162 if (strncmp(response, "OK", 2) == 0)
164 logprintf(LOG_INFO, "device online, "
165 "ready to receive remote codes");
166 return 1;
170 logprintf(LOG_ERR, "unexpected response from device");
171 return 0;
174 int tira_init(void)
176 LOGPRINTF (1, "Tira init");
177 if(!tty_create_lock(hw.device))
179 logprintf(LOG_ERR,"could not create lock files");
180 return 0;
182 if ( (hw.fd = open (hw.device, O_RDWR | O_NONBLOCK | O_NOCTTY)) < 0)
184 tty_delete_lock ();
185 logprintf (LOG_ERR, "Could not open the '%s' device",
186 hw.device);
187 return 0;
189 LOGPRINTF(1, "device '%s' opened", hw.device);
191 /* We want 9600 8N1 with CTS/RTS handshaking, lets set that
192 * up. The specs state a baud rate of 100000, looking at the
193 * ftdi_sio driver it forces the issue so we can set to what
194 * we would like. And seeing as this is mapped to 9600 under
195 * windows should be a safe bet.
197 if(!tty_reset(hw.fd) ||
198 !tty_setbaud(hw.fd, 9600) ||
199 !tty_setrtscts(hw.fd, 1))
201 tira_deinit();
202 return 0;
205 /* Device should be activated by this point... wait... */
206 usleep (50000);
208 if(!tira_setup())
210 tira_deinit();
211 return 0;
213 return 1;
216 int tira_deinit (void)
218 close(hw.fd);
219 sleep(1);
220 tty_delete_lock();
221 return 1;
224 char *tira_rec (struct ir_remote *remotes)
226 char *m;
227 int i, x;
229 last = end;
230 x = 0;
231 gettimeofday (&start, NULL);
232 for (i = 0 ; i < 6; i++)
234 if (i > 0)
236 if (!waitfordata(20000))
238 LOGPRINTF(0,"timeout reading byte %d",i);
239 /* likely to be !=6 bytes, so flush. */
240 tcflush(hw.fd, TCIFLUSH);
241 return NULL;
244 if (read(hw.fd, &b[i], 1) != 1)
246 logprintf(LOG_ERR, "reading of byte %d failed.", i);
247 logperror(LOG_ERR,NULL);
248 return NULL;
250 LOGPRINTF(1, "byte %d: %02x", i, b[i]);
251 x++;
253 gettimeofday(&end,NULL);
254 code = 0;
255 for ( i = 0 ; i < x ; i++ )
257 code |= ((ir_code) b[i]);
258 code = code << 8;
261 LOGPRINTF(1," -> %0llx",(unsigned long long) code);
263 m = decode_all(remotes);
264 return m;