[PATCH 1/4] ftdi: Refactor pulling pulse creation function by itself

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH 1/4] ftdi: Refactor pulling pulse creation function by itself

William Manley
The new `write_pulse` function is more functional and less dependent on
the other implementation details of the ftdi driver.  This will give me
more oppertunity to investigate its operation.
---
 plugins/ftdi.c | 46 ++++++++++++++++++++++++++++++++++------------
 1 file changed, 34 insertions(+), 12 deletions(-)

diff --git a/plugins/ftdi.c b/plugins/ftdi.c
index 7b214bb..bde939f 100644
--- a/plugins/ftdi.c
+++ b/plugins/ftdi.c
@@ -87,6 +87,9 @@ static lirc_t time_left(struct timeval* current, struct timeval* last, lirc_t ga
 }
 #endif
 
+static int modulate_pulses(unsigned char* buf, size_t size,
+ const int* pulseptr, int n_pulses, __u32 f_sample, __u32 f_carrier);
+
 static void list_devices(glob_t *buff)
 {
  struct ftdi_context* ctx;
@@ -469,29 +472,37 @@ static lirc_t hwftdi_readdata(lirc_t timeout)
  return res;
 }
 
-static int hwftdi_send(struct ir_remote* remote, struct ir_ncode* code)
+static ssize_t write_pulse(unsigned char* buf, size_t size,
+ 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];
 
  log_debug("hwftdi_send() carrier=%dHz f_sample=%dHz ", f_carrier, f_sample);
 
  /* initialize decoded buffer: */
  if (!send_buffer_put(remote, code))
- return 0;
+ return -1;
 
  /* init vars: */
  n_pulses = send_buffer_length();
  pulseptr = send_buffer_data();
+
+ return modulate_pulses(buf, size, pulseptr, n_pulses, f_sample, f_carrier);
+}
+
+static int modulate_pulses(unsigned char* buf, size_t size,
+ const int* pulseptr, int n_pulses, __u32 f_sample, __u32 f_carrier)
+{
+ __u32 div_carrier;
+ lirc_t pulse;
+ int pulsewidth;
+ int val_carrier;
+ int bufidx;
+ int sendpulse;
+
  bufidx = 0;
  div_carrier = 0;
  val_carrier = 0;
@@ -525,18 +536,29 @@ static int hwftdi_send(struct ir_remote* remote, struct ir_ncode* code)
 
  /* flush txbuffer? */
  /* note: be sure to have room for last '0' */
- if (bufidx >= (TXBUFSZ - 1)) {
+ if (bufidx >= (size - 1)) {
  log_error("buffer overflow while generating IR pattern");
- return 0;
+ return -1;
  }
  }
  }
 
  /* always end with 0 to turn off transmitter: */
  buf[bufidx++] = 0;
+ return bufidx;
+}
+
+static int hwftdi_send(struct ir_remote* remote, struct ir_ncode* code)
+{
+ unsigned char buf[TXBUFSZ];
+ ssize_t pulse_len;
+
+ pulse_len = write_pulse(buf, sizeof(buf), remote, code);
+ if (pulse_len == -1)
+ return 0;
 
  /* let the child process transmit the pattern */
- chk_write(pipe_main2tx[1], buf, bufidx);
+ chk_write(pipe_main2tx[1], buf, pulse_len);
 
  /* wait for child process to be ready with it */
  chk_read(pipe_tx2main[0], buf, 1);
--
2.8.0.rc3


------------------------------------------------------------------------------
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH 3/4] ftdi: Tear down subprocess if parent dies

William Manley
If the lircd parent process is killed with SIGKILL it will be unable
to call `hwftdi_deinit` and so the subprocess it spawned will continue
living, keeping the ftdi device busy.  This change uses receiving EOF
on the pipe from the parent process as a signal that the parent process
has died and will shut itself down accordingly too.
---
 plugins/ftdi.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/plugins/ftdi.c b/plugins/ftdi.c
index bd4725a..6467c0a 100644
--- a/plugins/ftdi.c
+++ b/plugins/ftdi.c
@@ -245,6 +245,9 @@ static void child_process(int fd_rx2main, int fd_main2tx, int fd_tx2main)
  ret = write(fd_tx2main, &ret, 1);
 
  continue;
+ } else if (ret == 0) {
+ /* EOF => The parent has died so the pipe has closed */
+ _exit(0);
  }
 
  /* receive IR */
--
2.8.0.rc3


------------------------------------------------------------------------------
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH 4/4] ftdi: Conform to lirc driver API v2 lifecycle expectations

William Manley
In reply to this post by William Manley
As documented in a1c63fe.  Specifically:

> * At some later point, lirc calls the deinit() func. This puts the
>   driver in a stand-by state, from which it is a reasonably fast
>   operation to call `init_func()` again.
> * As a last operation, lirc might call the `close()` func. This
>   relinquishes all resources allocated by the driver.
> * functions are not guaranteed to be executed in the order described.
>   In general, the driver should not break if e. g., the `init()` or
>   `deinit()` function is called twice.
---
 plugins/ftdi.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/plugins/ftdi.c b/plugins/ftdi.c
index 6467c0a..7cec9e7 100644
--- a/plugins/ftdi.c
+++ b/plugins/ftdi.c
@@ -292,6 +292,11 @@ static int hwftdi_init(void)
 
  char* p;
 
+ if (child_pid > 0) {
+ log_info("hwftdi_init: Already initialised");
+ return 1;
+ }
+
  log_info("Initializing FTDI: %s", drv.device);
 
  /* Parse the device string, which has the form key=value,
@@ -429,7 +434,7 @@ fail_start:
  return 0;
 }
 
-static int hwftdi_deinit(void)
+static int hwftdi_close(void)
 {
  if (child_pid != -1) {
  /* Kill the child process, and wait for it to exit */
@@ -590,9 +595,8 @@ const struct driver hw_ftdi = {
  .rec_mode = LIRC_MODE_MODE2,
  .code_length = 0,
  .init_func = hwftdi_init,
- .deinit_func = hwftdi_deinit,
  .open_func = default_open,
- .close_func = default_close,
+ .close_func = hwftdi_close,
  .send_func = hwftdi_send,
  .rec_func = hwftdi_rec,
  .decode_func = receive_decode,
--
2.8.0.rc3


------------------------------------------------------------------------------
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH 2/4] ftdi: Add support for duty_cycle in lirc configuration file

William Manley
In reply to this post by William Manley
An IR signal is modulated on a carrier.  The carrier consists of a square
wave of 0 and 1 at a default frequency of 38kHz.  The duty_cycle is the
percentage of the time that the carrier is at 1 rather than at 0 during
a carrier cycle.  It is in the range 1-99.
---
 plugins/ftdi.c | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/plugins/ftdi.c b/plugins/ftdi.c
index bde939f..bd4725a 100644
--- a/plugins/ftdi.c
+++ b/plugins/ftdi.c
@@ -88,7 +88,8 @@ static lirc_t time_left(struct timeval* current, struct timeval* last, lirc_t ga
 #endif
 
 static int modulate_pulses(unsigned char* buf, size_t size,
- const int* pulseptr, int n_pulses, __u32 f_sample, __u32 f_carrier);
+ const int* pulseptr, int n_pulses, __u32 f_sample, __u32 f_carrier,
+ unsigned int duty_cycle);
 
 static void list_devices(glob_t *buff)
 {
@@ -490,13 +491,16 @@ static ssize_t write_pulse(unsigned char* buf, size_t size,
  n_pulses = send_buffer_length();
  pulseptr = send_buffer_data();
 
- return modulate_pulses(buf, size, pulseptr, n_pulses, f_sample, f_carrier);
+ return modulate_pulses(buf, size, pulseptr, n_pulses, f_sample, f_carrier,
+    remote->duty_cycle);
 }
 
 static int modulate_pulses(unsigned char* buf, size_t size,
- const int* pulseptr, int n_pulses, __u32 f_sample, __u32 f_carrier)
+ const int* pulseptr, int n_pulses, __u32 f_sample, __u32 f_carrier,
+ unsigned int duty_cycle)
 {
  __u32 div_carrier;
+ __u32 duty;
  lirc_t pulse;
  int pulsewidth;
  int val_carrier;
@@ -508,6 +512,13 @@ static int modulate_pulses(unsigned char* buf, size_t size,
  val_carrier = 0;
  sendpulse = 0;
 
+ /* Calculate the carrier on time (in # samples) */
+ duty = f_sample * duty_cycle / 100;  /* duty_cycle is 1-100 */
+ if (duty <= 1)
+ duty = 1;
+ else if (duty >= f_sample)
+ duty = f_sample - 1;
+
  while (n_pulses--) {
  /* take pulse from buffer */
  pulse = *pulseptr++;
@@ -522,11 +533,11 @@ static int modulate_pulses(unsigned char* buf, size_t size,
  /* carrier generator (generates a carrier
  * continously, will be modulated by the
  * requested signal): */
- div_carrier += f_carrier * 2;
+ div_carrier += f_carrier;
  if (div_carrier >= f_sample) {
  div_carrier -= f_sample;
- val_carrier = val_carrier ? 0 : 255;
  }
+ val_carrier = div_carrier < duty ? 255 : 0;
 
  /* send carrier or send space ? */
  if (sendpulse)
--
2.8.0.rc3


------------------------------------------------------------------------------
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z
Loading...