Example #1
0
File: ftdi.c Project: andyvand/LIRC
static void parsesamples(unsigned char* buf, int n, int pipe_rxir_w)
{
	int i;
	lirc_t usecs;

	for (i = 0; i < n; i++) {
		int curstate = (buf[i] & (1 << input_pin)) != 0;

		rxctr++;
		if (curstate == laststate)
			continue;

		/* Convert number of samples to us.
		 *
		 * The datasheet indicates that the sample rate in
		 * bitbang mode is 16 times the baud rate but 32 seems
		 * to be correct. */
		usecs = (rxctr * 1000000LL) / (rx_baud_rate * 32);

		/* Clamp */
		if (usecs > PULSE_MASK)
			usecs = PULSE_MASK;

		/* Indicate pulse or bit */
		if (curstate)
			usecs |= PULSE_BIT;

		/* Send the sample */
		chk_write(pipe_rxir_w, &usecs, sizeof(usecs));

		/* Remember last state */
		laststate = curstate;
		rxctr = 0;
	}
}
Example #2
0
/*
 * Given a directory in /sys/class/rc, check if it contains
 * a file called device. If so, write "lirc" to the protocols
 * file in same directory unless the 'lirc' protocol already
 * is enabled.
 *
 * rc_dir: directory specification like rc0, rc1, etc.
 * device: Device given to lirc,  like 'lirc0' (or /dev/lirc0).
 * Returns: 0 if OK, else -1.
 *
 */
static int visit_rc(const char* rc_dir, const char* device)
{
	char path[64];
	char buff[128];
	char* enabled = NULL;
	int fd;
	int r;

	snprintf(path, sizeof(path), "/sys/class/rc/%s", rc_dir);
	if (access(path, F_OK) != 0) {
		log_notice("Cannot open rc directory: %s", path);
		return -1;
	}
	snprintf(path, sizeof(path), "/sys/class/rc/%s/%s", rc_dir, device);
	if (access(path, F_OK) != 0) {
		log_debug("No device found: %s", path);
		return -1;
	}
	snprintf(path, sizeof(path), "/sys/class/rc/%s/protocols", rc_dir);
	fd = open(path, O_RDONLY);
	if (fd < 0) {
		log_debug(
			  "Cannot open protocol file: %s for read", path);
		return -1;
	}
	r = read(fd, buff, sizeof(buff));
	if (r < 0) {
		log_debug("Cannot read from %s", path);
		return -1;
	}
	if (strchr(buff, '[') != NULL) {
		enabled = strchr(buff, '[') + 1;
		if (strchr(buff, ']') != NULL)
			*strchr(buff, ']') = '\0';
		else
			enabled = NULL;
	}
	if (enabled == NULL) {
		log_warn("Cannot parse protocols %s", buff);
	} else  if (strcmp(enabled, "lirc") == 0) {
		log_info("[lirc] protocol is enabled");
		return 0;
	}
	fd = open(path, O_WRONLY);
	if (fd < 0) {
		log_debug(
			  "Cannot open protocol file for write: %s", path);
		return -1;
	}
	chk_write(fd, "lirc\n", 5);
	log_notice("'lirc' written to protocols file %s", path);
	close(fd);
	return 0;
}
Example #3
0
File: ftdi.c Project: andyvand/LIRC
static int hwftdi_send(struct ir_remote* remote, struct ir_ncode* code)
{
	__u32 f_sample = tx_baud_rate * 8;
	__u32 f_carrier = remote->freq == 0 ? DEFAULT_FREQ : remote->freq;
	__u32 div_carrier;
	int val_carrier;
	const lirc_t* pulseptr;
	lirc_t pulse;
	int n_pulses;
	int pulsewidth;
	int bufidx;
	int sendpulse;
	unsigned char buf[TXBUFSZ];

	logprintf(LIRC_DEBUG, "hwftdi_send() carrier=%dHz f_sample=%dHz ", f_carrier, f_sample);

	/* initialize decoded buffer: */
	if (!send_buffer_put(remote, code))
		return 0;

	/* init vars: */
	n_pulses = send_buffer_length();
	pulseptr = send_buffer_data();
	bufidx = 0;
	div_carrier = 0;
	val_carrier = 0;
	sendpulse = 0;

	while (n_pulses--) {
		/* take pulse from buffer */
		pulse = *pulseptr++;

		/* compute the pulsewidth (in # samples) */
		pulsewidth = ((__u64)f_sample) * ((__u32)(pulse & PULSE_MASK)) / 1000000ul;

		/* toggle pulse / space */
		sendpulse = sendpulse ? 0 : 1;

		while (pulsewidth--) {
			/* carrier generator (generates a carrier
			 * continously, will be modulated by the
			 * requested signal): */
			div_carrier += f_carrier * 2;
			if (div_carrier >= f_sample) {
				div_carrier -= f_sample;
				val_carrier = val_carrier ? 0 : 255;
			}

			/* send carrier or send space ? */
			if (sendpulse)
				buf[bufidx++] = val_carrier;
			else
				buf[bufidx++] = 0;

			/* flush txbuffer? */
			/* note: be sure to have room for last '0' */
			if (bufidx >= (TXBUFSZ - 1)) {
				logprintf(LIRC_ERROR, "buffer overflow while generating IR pattern");
				return 0;
			}
		}
	}

	/* always end with 0 to turn off transmitter: */
	buf[bufidx++] = 0;

	/* let the child process transmit the pattern */
	chk_write(pipe_main2tx[1], buf, bufidx);

	/* wait for child process to be ready with it */
	chk_read(pipe_tx2main[0], buf, 1);

	return 1;
}
Example #4
0
/**
 *	Runtime that reads device, forwards codes to main thread
 *	and simulates repetitions.
 */
static void* atwf83_repeat(void* arg)
{
	int repeat_count = 0;
	unsigned ev[2];
	unsigned current_code;
	int rd, sel;
	fd_set files;
	struct timeval delay;
	int pressed = 0;
	int fd = fd_pipe[1];

	while (1) {
		// Initialize set to monitor device's events
		FD_ZERO(&files);
		FD_SET(fd_hidraw, &files);
		if (pressed)
			sel = select(FD_SETSIZE, &files, NULL, NULL, &delay);
		else
			sel = select(FD_SETSIZE, &files, NULL, NULL, NULL);

		switch (sel) {
		case 1:
			// Data ready in device's file
			rd = read(fd_hidraw, ev, sizeof(ev));

			if (rd == -1) {
				// Error
				logprintf(LIRC_ERROR,
					  "(%s) Could not read %s",
					   __func__, drv.device);
				goto exit_loop;
			}
			if ((rd == 8 && ev[0] != 0) || (rd == 6 && ev[0] > 2)) {
				// Key code : forward it to main thread
				pressed = 1;
				repeat_count = 0;
				delay.tv_sec = 0;
				delay.tv_usec = repeat_time1_us;
				current_code = ev[0];
			} else {
				// Release code : stop repetitions
				pressed = 0;
				current_code = release_code;
			}
			break;
		case 0:
			repeat_count++;
			if (repeat_count >= max_repeat_count) {
				// Too many repetitions, something must have gone wrong
				logprintf(LIRC_ERROR, "(%s) too many repetitions", __func__);

				goto exit_loop;
			}
			// Timeout : send current_code again to main
			//           thread to simulate repetition
			delay.tv_sec = 0;
			delay.tv_usec = repeat_time2_us;
			break;
		default:
			// Error
			logprintf(LIRC_ERROR,
				  "(%s) select() failed", __func__);
			goto exit_loop;
		}
		// Send code to main thread through pipe
		chk_write(fd, &current_code, sizeof(current_code));
	}
exit_loop:

	// Wake up main thread with special key code
	current_code = remove_code;
	chk_write(fd, &current_code, sizeof(current_code));
	return NULL;
}