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.
38 #include <sys/types.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)
50 #define HEXDUMP(buf, len) hexdump(buf, len)
52 #define HEXDUMP(buf, len)
60 struct timeval pre_delay
;
61 struct timeval pre_time
;
65 const int unit
= UIRT2_UNIT
;
66 //static int debug = 3;
68 static ssize_t
readagain(int fd
, void *buf
, size_t count
)
72 struct timeval timeout
= { .tv_sec
= 0, .tv_usec
= 200000 };
75 rc
=read(fd
, buf
, count
);
82 while( (rc
== -1 && errno
== EAGAIN
) || (rc
>= 0 && pos
< count
) )
87 rc
=select(fd
+ 1, &fds
, NULL
, NULL
, &timeout
);
96 /* continue for EAGAIN case */
100 rc
=read(fd
, ((char *)buf
) + pos
, count
-pos
);
108 return (pos
== 0) ? -1 : pos
;
112 static void hexdump(byte_t
*buf
, int len
)
118 for (i
= 0; i
< len
; i
++) {
119 if (pos
+ 3 >= sizeof(str
)) {
127 sprintf(str
+ pos
, "%02x ", buf
[i
]);
132 logprintf(LOG_DEBUG
, "%s", str
);
137 static int mywaitfordata(uirt2_t
*dev
, long usec
) {
150 ret
= select(maxfd
+ 1, &fds
, NULL
, NULL
, &tv
);
159 static int uirt2_readflush(uirt2_t
*dev
, long timeout
)
164 while(mywaitfordata(dev
, timeout
) > 0) {
165 res
= readagain(dev
->fd
, &c
, 1);
174 static byte_t
checksum(byte_t
*data
, int len
)
179 for (i
= 0; i
< len
; i
++) {
180 check
= check
- data
[i
];
187 static int command_ext(uirt2_t
*dev
, const byte_t
*in
, byte_t
*out
)
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
))
202 struct timeval delay
;
204 gettimeofday(&cur
, NULL
);
205 timersub(&cur
, &dev
->pre_time
, &diff
);
208 if(timercmp(&dev
->pre_delay
, &diff
, >))
210 timersub(&dev
->pre_delay
, &diff
, &delay
);
213 LOGPRINTF(1, "udelay %lu %lu",
214 delay
.tv_sec
, delay
.tv_usec
);
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);
230 logprintf(LOG_ERR
, "uirt2_raw: couldn't write command");
234 LOGPRINTF(1, "wrote %d", res
);
236 if (!mywaitfordata(dev
, (long) 1000000)) {
237 logprintf(LOG_ERR
, "uirt2_raw: did not receive results");
241 res
= readagain(dev
->fd
, out
+ 1, out
[0]);
244 logprintf(LOG_ERR
, "uirt2_raw: couldn't read command result");
248 LOGPRINTF(1, "cmd res %d:", res
);
249 HEXDUMP(out
+ 1, out
[0]);
253 int check
= checksum(out
+ 1, out
[0]);
256 logprintf(LOG_ERR
, "uirt2_raw: checksum error");
265 static int command(uirt2_t
*dev
, const byte_t
*buf
, int len
)
270 memcpy(in
+ 1, buf
, len
+1);
274 if (command_ext(dev
, in
, out
) < 0) {
278 return out
[1] < UIRT2_CSERROR
;
282 static unsigned long calc_bits_length(remstruct1_data_t
*buf
)
286 unsigned long len
= 0;
288 for (i
= 0; i
< buf
->bBits
; i
++) {
292 b
= buf
->bDatBits
[i
/ 8];
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
);
336 uirt2_t
*uirt2_init(int fd
)
338 uirt2_t
*dev
= (uirt2_t
*)malloc(sizeof(uirt2_t
));
342 logprintf(LOG_ERR
, "uirt2_raw: out of memory");
346 memset(dev
, 0, sizeof(uirt2_t
));
348 timerclear(&dev
->pre_time
);
350 dev
->flags
= UIRT2_MODE_UIR
;
353 uirt2_readflush(dev
, 200000);
355 if(uirt2_getversion(dev
, &dev
->version
) < 0) {
360 if(dev
->version
< 0x0104) {
361 logprintf(LOG_WARNING
, "uirt2_raw: Old UIRT hardware");
363 logprintf(LOG_INFO
, "uirt2_raw: UIRT version %04x ok",
371 int uirt2_uninit(uirt2_t
*dev
)
378 int uirt2_getmode(uirt2_t
*dev
)
380 return (dev
->flags
& UIRT2_MODE_MASK
);
384 int uirt2_setmode(uirt2_t
*dev
, int mode
)
389 if (uirt2_getmode(dev
) == mode
)
391 LOGPRINTF(1, "uirt2_setmode: already in requested mode");
397 cmd
= UIRT2_SETMODEUIR
;
400 cmd
= UIRT2_SETMODERAW
;
402 case UIRT2_MODE_STRUC
:
403 cmd
= UIRT2_SETMODESTRUC
;
406 logprintf(LOG_ERR
, "uirt2_raw: bad mode");
412 if (command(dev
, buf
, 0) < 0) {
413 logprintf(LOG_ERR
, "uirt2_raw: setmode failed");
417 dev
->flags
= (dev
->flags
& ~UIRT2_MODE_MASK
) | mode
;
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
)
445 if(dev
->version
!= 0)
447 *version
= dev
->version
;
452 in
[1] = UIRT2_GETVERSION
;
455 if (command_ext(dev
, in
, out
) >= 0) {
456 *version
= out
[2] + (out
[1] << 8);
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);
471 if (command_ext(dev
, in
, out
) >= 0) {
472 *version
= out
[2] + (out
[1] << 8);
480 int uirt2_getgpiocaps(uirt2_t
*dev
, int *slots
, byte_t masks
[4])
486 in
[1] = UIRT2_GETGPIOCAPS
;
491 if (command_ext(dev
, in
, out
) < 0) {
496 memcpy(masks
, out
+ 2, 4);
501 int uirt2_getgpiocfg(uirt2_t
*dev
, int slot
, uirt2_code_t code
,
502 int *action
, int *duration
)
508 in
[1] = UIRT2_GETGPIOCFG
;
513 if(command_ext(dev
, in
, out
) < 0) {
517 memcpy(code
, out
+ 1, UIRT2_CODE_SIZE
);
518 *action
= out
[UIRT2_CODE_SIZE
+ 1];
519 *duration
= out
[UIRT2_CODE_SIZE
+ 2] * 5;
524 int uirt2_setgpiocfg(uirt2_t
*dev
, int slot
, uirt2_code_t code
,
525 int action
, int duration
)
530 in
[1] = UIRT2_SETGPIOCFG
;
531 in
[2] = 4 + UIRT2_CODE_SIZE
;
534 memcpy(in
+ 4, code
, UIRT2_CODE_SIZE
);
537 in
[11] = duration
/ 5;
539 return command(dev
, in
+ 1, in
[0]);
543 int uirt2_getgpio(uirt2_t
*dev
, byte_t ports
[4])
549 in
[1] = UIRT2_GETGPIO
;
553 if(command_ext(dev
, in
, out
) < 0) {
557 memcpy(ports
, out
+ 1, 4);
562 int uirt2_setgpio(uirt2_t
*dev
, int action
, int duration
)
566 buf
[0] = UIRT2_SETGPIO
;
569 buf
[3] = duration
/ 5;
571 return command(dev
, buf
, 3);
575 int uirt2_refreshgpio(uirt2_t
*dev
)
579 buf
[0] = UIRT2_REFRESHGPIO
;
582 return command(dev
, buf
, 1);
586 int uirt2_read_uir(uirt2_t
*dev
, byte_t
*buf
, int length
)
591 if (uirt2_getmode(dev
) != UIRT2_MODE_UIR
) {
592 logprintf(LOG_ERR
, "uirt2_raw: Not in UIR mode");
597 res
= readagain(dev
->fd
, buf
+ pos
, 1);
614 lirc_t
uirt2_read_raw(uirt2_t
*dev
, lirc_t timeout
)
617 static int pulse
= 0;
619 if (uirt2_getmode(dev
) != UIRT2_MODE_RAW
) {
620 logprintf(LOG_ERR
, "uirt2_raw: Not in RAW mode");
628 if (!waitfordata(timeout
))
631 res
= readagain(dev
->fd
, &b
, 1);
637 LOGPRINTF(3, "read_raw %02x", b
);
644 if (dev
->new_signal
) {
648 LOGPRINTF(1, "dev->new_signal");
650 res
= readagain(dev
->fd
, &isdly
[1], 1);
656 data
= UIRT2_UNIT
* (256 * isdly
[0] + isdly
[1]);
660 data
= UIRT2_UNIT
* b
;
662 data
= data
| PULSE_BIT
;
675 int uirt2_send_raw(uirt2_t
*dev
, byte_t
*buf
, int length
)
679 tmp
[0] = UIRT2_DOTXRAW
;
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
)
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;
705 rem_ext
.bFrequency
= ((5000000 / freq
) + 1)/2;
707 rem_ext
.bRepeatCount
= bRepeatCount
;
708 memcpy(&rem_ext
.data
, buf
, sizeof(*buf
));
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);
718 if(bRepeatCount
> 0x1f)
720 rem
.bCmd
= uirt2_calc_freq(freq
) + 0x1f;
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
);
742 int uirt2_calc_freq(int freq
)
745 return UIRT2_FREQ_40
;
746 } else if (freq
> 37000) {
747 return UIRT2_FREQ_38
;
749 return UIRT2_FREQ_36
;