Little fix.
[irreco.git] / lirc-0.8.4a / daemons / hw_uirt2_common.c
blobd0e35ee75ee7dd9f3f2bbb1872303286a2a8241c
1 /* $Id: hw_uirt2_common.c,v 5.6 2008/03/30 14:52:04 lirc Exp $ */
3 /****************************************************************************
4 ** hw_uirt2_common.c *******************************************************
5 ****************************************************************************
7 * Routines for UIRT2 receiver/transmitter
9 * UIRT2 web site: http://users.skynet.be/sky50985/
11 * Copyright (C) 2003 Mikael Magnusson <mikma@users.sourceforge.net>
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Library General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 #ifdef HAVE_CONFIG_H
30 # include <config.h>
31 #endif
32 //#define DEBUG
34 #include <stdio.h>
35 #include <unistd.h>
36 #include <string.h>
37 #include <sys/time.h>
38 #include <sys/types.h>
39 #include <fcntl.h>
40 #include <stdarg.h>
41 #include <errno.h>
42 #include "serial.h"
43 #include "lircd.h"
44 #include "hw_uirt2_common.h"
46 #define PRINT_TIME(a) \
47 LOGPRINTF(1, "time: %s %li %li", #a, (a)->tv_sec, (a)->tv_usec)
49 #ifdef DEBUG
50 #define HEXDUMP(buf, len) hexdump(buf, len)
51 #else
52 #define HEXDUMP(buf, len)
53 #endif
55 struct tag_uirt2_t {
56 int fd;
57 int flags;
58 int version;
60 struct timeval pre_delay;
61 struct timeval pre_time;
62 int new_signal;
65 const int unit = UIRT2_UNIT;
66 //static int debug = 3;
68 static ssize_t readagain(int fd, void *buf, size_t count)
70 ssize_t rc;
71 size_t pos=0;
72 struct timeval timeout = { .tv_sec = 0, .tv_usec = 200000 };
73 fd_set fds;
75 rc=read(fd, buf, count);
77 if(rc > 0)
79 pos+=rc;
82 while( (rc == -1 && errno == EAGAIN) || (rc >= 0 && pos < count) )
84 FD_ZERO(&fds);
85 FD_SET(fd,&fds);
87 rc=select(fd + 1, &fds, NULL, NULL, &timeout);
89 if(rc == 0)
91 /* timeout */
92 break;
94 else if(rc == -1)
96 /* continue for EAGAIN case */
97 continue;
100 rc=read(fd, ((char *)buf) + pos, count-pos);
102 if(rc > 0)
104 pos+=rc;
108 return (pos == 0) ? -1 : pos;
111 #ifdef DEBUG
112 static void hexdump(byte_t *buf, int len)
114 int i;
115 char str[200];
116 int pos = 0;
118 for (i = 0; i < len; i++) {
119 if (pos + 3 >= sizeof(str)) {
120 break;
123 if (!(i % 8)) {
124 str[pos++] = ' ';
127 sprintf(str + pos, "%02x ", buf[i]);
129 pos += 3;
132 logprintf(LOG_DEBUG, "%s", str);
134 #endif /* DEBUG */
137 static int mywaitfordata(uirt2_t *dev, long usec) {
138 int fd = dev->fd;
139 fd_set fds;
140 int maxfd = fd;
141 int ret;
142 struct timeval tv;
144 FD_ZERO(&fds);
145 FD_SET(fd,&fds);
147 tv.tv_sec = 0;
148 tv.tv_usec = usec;
150 ret = select(maxfd + 1, &fds, NULL, NULL, &tv);
152 if (ret <= 0) {
153 return 0;
154 } else {
155 return 1;
159 static int uirt2_readflush(uirt2_t *dev, long timeout)
161 int res;
162 char c;
164 while(mywaitfordata(dev, timeout) > 0) {
165 res = readagain(dev->fd, &c, 1);
166 if (res < 1) {
167 return -1;
170 return 0;
174 static byte_t checksum(byte_t *data, int len)
176 int check = 0;
177 int i;
179 for (i = 0; i < len; i++) {
180 check = check - data[i];
183 return check & 0xff;
187 static int command_ext(uirt2_t *dev, const byte_t *in, byte_t *out)
189 byte_t tmp[1024];
190 int res;
191 int len = in[0];
192 const byte_t *buf = in + 1;
194 memcpy(tmp, buf, len + 1);
196 tmp[len + 1] = checksum(tmp, len + 1) & 0xff;
198 if (timerisset(&dev->pre_delay))
200 struct timeval cur;
201 struct timeval diff;
202 struct timeval delay;
204 gettimeofday(&cur, NULL);
205 timersub(&cur, &dev->pre_time, &diff);
206 PRINT_TIME(&diff);
208 if(timercmp(&dev->pre_delay, &diff, >))
210 timersub(&dev->pre_delay, &diff, &delay);
211 PRINT_TIME(&delay);
213 LOGPRINTF(1, "udelay %lu %lu",
214 delay.tv_sec, delay.tv_usec);
215 sleep(delay.tv_sec);
216 usleep(delay.tv_usec);
219 timerclear(&dev->pre_delay);
222 uirt2_readflush(dev, 0);
224 LOGPRINTF(1, "writing command %02x", buf[0]);
226 HEXDUMP(tmp, len + 2);
227 res = write(dev->fd, tmp, len + 2);
229 if (res < len + 2) {
230 logprintf(LOG_ERR, "uirt2_raw: couldn't write command");
231 return -1;
234 LOGPRINTF(1, "wrote %d", res);
236 if (!mywaitfordata(dev, (long) 1000000)) {
237 logprintf(LOG_ERR, "uirt2_raw: did not receive results");
238 return -1;
241 res = readagain(dev->fd, out + 1, out[0]);
243 if (res < out[0]) {
244 logprintf(LOG_ERR, "uirt2_raw: couldn't read command result");
245 return -1;
248 LOGPRINTF(1, "cmd res %d:", res);
249 HEXDUMP(out + 1, out[0]);
250 LOGPRINTF(1, "");
252 if (out[0] > 1) {
253 int check = checksum(out + 1, out[0]);
255 if (check != 0) {
256 logprintf(LOG_ERR, "uirt2_raw: checksum error");
257 return -1;
261 return 0;
265 static int command(uirt2_t *dev, const byte_t *buf, int len)
267 byte_t in[1024];
268 byte_t out[2];
270 memcpy(in + 1, buf, len+1);
271 in[0] = len;
272 out[0] = 1;
274 if (command_ext(dev, in, out) < 0) {
275 return -1;
278 return out[1] < UIRT2_CSERROR;
282 static unsigned long calc_bits_length(remstruct1_data_t *buf)
284 int i;
285 byte_t b = 0;
286 unsigned long len = 0;
288 for (i = 0; i < buf->bBits; i++) {
289 int bit;
291 if (!(i % 8)) {
292 b = buf->bDatBits[i / 8];
295 bit = b & 1;
296 b = b >> 1;
298 if (i % 2) {
299 // Odd
300 if (bit) {
301 len += buf->bOff1;
302 } else {
303 len += buf->bOff0;
305 } else {
306 // Even
307 if (bit) {
308 len += buf->bOn1;
309 } else {
310 len += buf->bOn0;
315 return unit * len;
319 static unsigned long calc_struct1_length(int repeat, remstruct1_data_t *buf)
321 int bISDly = unit * (buf->bISDlyLo + 256 * buf->bISDlyHi);
322 int bHdr = unit * (buf->bHdr1 + buf->bHdr0);
323 unsigned long bBitLength = calc_bits_length(buf);
325 LOGPRINTF(1, "bBitLength %lu repeat %d", bBitLength, repeat);
327 return (repeat + 1) * (bISDly + bHdr + bBitLength);
333 * Exported functions
336 uirt2_t *uirt2_init(int fd)
338 uirt2_t *dev = (uirt2_t *)malloc(sizeof(uirt2_t));
340 if(dev == NULL)
342 logprintf(LOG_ERR, "uirt2_raw: out of memory");
343 return NULL;
346 memset(dev, 0, sizeof(uirt2_t));
348 timerclear(&dev->pre_time);
349 dev->new_signal = 1;
350 dev->flags = UIRT2_MODE_UIR;
351 dev->fd = fd;
353 uirt2_readflush(dev, 200000);
355 if(uirt2_getversion(dev, &dev->version) < 0) {
356 free(dev);
357 return NULL;
360 if(dev->version < 0x0104) {
361 logprintf(LOG_WARNING, "uirt2_raw: Old UIRT hardware");
362 } else {
363 logprintf(LOG_INFO, "uirt2_raw: UIRT version %04x ok",
364 dev->version);
367 return dev;
371 int uirt2_uninit(uirt2_t *dev)
373 free(dev);
374 return 0;
378 int uirt2_getmode(uirt2_t *dev)
380 return (dev->flags & UIRT2_MODE_MASK);
384 int uirt2_setmode(uirt2_t *dev, int mode)
386 byte_t buf[20];
387 byte_t cmd;
389 if (uirt2_getmode(dev) == mode)
391 LOGPRINTF(1, "uirt2_setmode: already in requested mode");
392 return 0;
395 switch(mode) {
396 case UIRT2_MODE_UIR:
397 cmd = UIRT2_SETMODEUIR;
398 break;
399 case UIRT2_MODE_RAW:
400 cmd = UIRT2_SETMODERAW;
401 break;
402 case UIRT2_MODE_STRUC:
403 cmd = UIRT2_SETMODESTRUC;
404 break;
405 default:
406 logprintf(LOG_ERR, "uirt2_raw: bad mode");
407 return -1;
410 buf[0] = cmd;
412 if (command(dev, buf, 0) < 0) {
413 logprintf(LOG_ERR, "uirt2_raw: setmode failed");
414 return -1;
417 dev->flags = (dev->flags & ~UIRT2_MODE_MASK) | mode;
418 return 0;
422 int uirt2_setmodeuir(uirt2_t *dev)
424 return uirt2_setmode(dev, UIRT2_MODE_UIR);
428 int uirt2_setmoderaw(uirt2_t *dev)
430 return uirt2_setmode(dev, UIRT2_MODE_RAW);
434 int uirt2_setmodestruc(uirt2_t *dev)
436 return uirt2_setmode(dev, UIRT2_MODE_STRUC);
440 int uirt2_getversion(uirt2_t *dev, int *version)
442 byte_t out[20];
443 byte_t in[20];
445 if(dev->version != 0)
447 *version = dev->version;
448 return 0;
451 in[0] = 0;
452 in[1] = UIRT2_GETVERSION;
453 out[0] = 3;
455 if (command_ext(dev, in, out) >= 0) {
456 *version = out[2] + (out[1] << 8);
457 return 0;
461 * Ok, that command didn't work. Maybe we're
462 * dealing with a newer version of the UIRT2
463 * protocol, which sends extended information when
464 * the version is requested.
466 LOGPRINTF(0, "uirt2: detection of uirt2 failed");
467 LOGPRINTF(0, "uirt2: trying to detect newer uirt firmware");
468 uirt2_readflush(dev, 200000);
470 out[0] = 8;
471 if (command_ext(dev, in, out) >= 0) {
472 *version = out[2] + (out[1] << 8);
473 return 0;
476 return -1;
480 int uirt2_getgpiocaps(uirt2_t *dev, int *slots, byte_t masks[4])
482 byte_t in[3];
483 byte_t out[6];
485 in[0] = 1;
486 in[1] = UIRT2_GETGPIOCAPS;
487 in[2] = 1;
489 out[0] = 6;
491 if (command_ext(dev, in, out) < 0) {
492 return -1;
495 *slots = out[1];
496 memcpy(masks, out + 2, 4);
497 return 0;
501 int uirt2_getgpiocfg(uirt2_t *dev, int slot, uirt2_code_t code,
502 int *action, int *duration)
504 byte_t in[4];
505 byte_t out[10];
507 in[0] = 2;
508 in[1] = UIRT2_GETGPIOCFG;
509 in[2] = 2;
510 in[3] = slot;
511 out[0] = 9;
513 if(command_ext(dev, in, out) < 0) {
514 return -1;
517 memcpy(code, out + 1, UIRT2_CODE_SIZE);
518 *action = out[UIRT2_CODE_SIZE + 1];
519 *duration = out[UIRT2_CODE_SIZE + 2] * 5;
520 return 0;
524 int uirt2_setgpiocfg(uirt2_t *dev, int slot, uirt2_code_t code,
525 int action, int duration)
527 byte_t in[12];
529 in[0] = 2;
530 in[1] = UIRT2_SETGPIOCFG;
531 in[2] = 4 + UIRT2_CODE_SIZE;
532 in[3] = slot;
534 memcpy(in + 4, code, UIRT2_CODE_SIZE);
536 in[10] = action;
537 in[11] = duration / 5;
539 return command(dev, in + 1, in[0]);
543 int uirt2_getgpio(uirt2_t *dev, byte_t ports[4])
545 byte_t in[3];
546 byte_t out[6];
548 in[0] = 21;
549 in[1] = UIRT2_GETGPIO;
550 in[2] = 1;
551 out[0] = 5;
553 if(command_ext(dev, in, out) < 0) {
554 return -1;
557 memcpy(ports, out + 1, 4);
558 return 0;
562 int uirt2_setgpio(uirt2_t *dev, int action, int duration)
564 byte_t buf[20];
566 buf[0] = UIRT2_SETGPIO;
567 buf[1] = 3;
568 buf[2] = action;
569 buf[3] = duration / 5;
571 return command(dev, buf, 3);
575 int uirt2_refreshgpio(uirt2_t *dev)
577 byte_t buf[2];
579 buf[0] = UIRT2_REFRESHGPIO;
580 buf[1] = 1;
582 return command(dev, buf, 1);
586 int uirt2_read_uir(uirt2_t *dev, byte_t *buf, int length)
588 int pos = 0;
589 int res;
591 if (uirt2_getmode(dev) != UIRT2_MODE_UIR) {
592 logprintf(LOG_ERR, "uirt2_raw: Not in UIR mode");
593 return -1;
596 while (1) {
597 res = readagain(dev->fd, buf + pos, 1);
599 if (res == -1) {
600 return pos;
603 pos += res;
605 if (pos == 6) {
606 break;
610 return pos;
614 lirc_t uirt2_read_raw(uirt2_t *dev, lirc_t timeout)
616 lirc_t data;
617 static int pulse = 0;
619 if (uirt2_getmode(dev) != UIRT2_MODE_RAW) {
620 logprintf(LOG_ERR, "uirt2_raw: Not in RAW mode");
621 return -1;
624 while (1) {
625 int res;
626 byte_t b;
628 if (!waitfordata(timeout))
629 return 0;
631 res = readagain(dev->fd, &b, 1);
633 if (res == -1) {
634 return 0;
637 LOGPRINTF(3, "read_raw %02x", b);
639 if (b == 0xff) {
640 dev->new_signal = 1;
641 continue;
644 if (dev->new_signal) {
645 byte_t isdly[2];
647 isdly[0] = b;
648 LOGPRINTF(1, "dev->new_signal");
650 res = readagain(dev->fd, &isdly[1], 1);
652 if (res == -1) {
653 return 0;
656 data = UIRT2_UNIT * (256 * isdly[0] + isdly[1]);
657 pulse = 1;
658 dev->new_signal = 0;
659 } else {
660 data = UIRT2_UNIT * b;
661 if (pulse) {
662 data = data | PULSE_BIT;
665 pulse = !pulse;
668 return data;
671 return 0;
675 int uirt2_send_raw(uirt2_t *dev, byte_t *buf, int length)
677 byte_t tmp[1024];
679 tmp[0] = UIRT2_DOTXRAW;
680 tmp[1] = length + 1;
681 memcpy(tmp + 2, buf, length);
683 return command(dev, tmp, length + 1);
687 int uirt2_send_struct1(uirt2_t *dev, int freq, int bRepeatCount,
688 remstruct1_data_t *buf)
690 int res;
691 unsigned long delay;
692 remstruct1_t rem;
693 remstruct1_ext_t rem_ext;
695 if(dev->version >= 0x0905)
697 byte_t tmp[2+sizeof(remstruct1_ext_t)];
699 if(freq == 0 || ((5000000 / freq) + 1)/2 >= 0x80)
701 rem_ext.bFrequency = 0x80;
703 else
705 rem_ext.bFrequency = ((5000000 / freq) + 1)/2;
707 rem_ext.bRepeatCount = bRepeatCount;
708 memcpy(&rem_ext.data, buf, sizeof(*buf));
710 tmp[0] = 0x37;
711 tmp[1] = sizeof(rem_ext) + 1;
713 memcpy(tmp + 2, &rem_ext, sizeof(rem_ext));
714 res = command(dev, tmp, sizeof(rem_ext) + 1);
716 else
718 if(bRepeatCount > 0x1f)
720 rem.bCmd = uirt2_calc_freq(freq) + 0x1f;
722 else
724 rem.bCmd = uirt2_calc_freq(freq) + bRepeatCount;
726 memcpy(&rem.data, buf, sizeof(*buf));
728 res = command(dev, (byte_t *) &rem, sizeof(rem) - 2);
730 delay = calc_struct1_length(bRepeatCount, buf);
731 gettimeofday(&dev->pre_time, NULL);
732 dev->pre_delay.tv_sec = delay / 1000000;
733 dev->pre_delay.tv_usec = delay % 1000000;
735 LOGPRINTF(1, "set dev->pre_delay %lu %lu",
736 dev->pre_delay.tv_sec, dev->pre_delay.tv_usec);
738 return res;
742 int uirt2_calc_freq(int freq)
744 if (freq > 39000) {
745 return UIRT2_FREQ_40;
746 } else if (freq > 37000) {
747 return UIRT2_FREQ_38;
748 } else {
749 return UIRT2_FREQ_36;