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; } }
/* * 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; }
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; }
/** * 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, ¤t_code, sizeof(current_code)); } exit_loop: // Wake up main thread with special key code current_code = remove_code; chk_write(fd, ¤t_code, sizeof(current_code)); return NULL; }