Module: xenomai-abe
Branch: analogy
Commit: bee38acc8bed264547102a3013c76408235485e7
URL:    
http://git.xenomai.org/?p=xenomai-abe.git;a=commit;h=bee38acc8bed264547102a3013c76408235485e7

Author: Alexis Berlemont <alexis.berlem...@gmail.com>
Date:   Sat Oct 16 14:59:54 2010 +0200

analogy: add first version of waveform generation

This work is based on Daniele Nicolodi's work. Unfortunately, I could
not include the proprosal as is because it was limited for 16bits
acquisition devices.

So far, this work is not complete.

---

 src/utils/analogy/Makefile.am         |    6 ++
 src/utils/analogy/signal_generation.c |  157 +++++++++++++++++++++++++++++++++
 src/utils/analogy/signal_generation.h |   38 ++++++++
 3 files changed, 201 insertions(+), 0 deletions(-)

diff --git a/src/utils/analogy/Makefile.am b/src/utils/analogy/Makefile.am
index f82942e..3d8cb5e 100644
--- a/src/utils/analogy/Makefile.am
+++ b/src/utils/analogy/Makefile.am
@@ -9,6 +9,12 @@ CPPFLAGS = \
 LDFLAGS = \
        @XENO_USER_LDFLAGS@
 
+lib_LIBRARIES = libwaveform.a
+
+libwaveform_a_SOURCES = signal_generation.c
+
+noinst_HEADERS = signal_generation.h
+
 analogy_config_SOURCES = analogy_config.c
 analogy_config_LDADD = \
        ../../drvlib/analogy/libanalogy.la \
diff --git a/src/utils/analogy/signal_generation.c 
b/src/utils/analogy/signal_generation.c
new file mode 100644
index 0000000..2f443c5
--- /dev/null
+++ b/src/utils/analogy/signal_generation.c
@@ -0,0 +1,157 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+#include <math.h>
+
+#include <analogy/analogy.h>
+
+#include "signal_generation.h"
+
+#ifndef PI
+#define PI 3.14159265358979323846
+#endif
+
+void a4l_sg_init_sine(struct waveform_config *config, double *values)
+{
+       int i;
+
+       double ratio = config->wf_frequency / config->spl_frequency;
+
+       for (i = 0; i < config->spl_count; i++) {
+
+               values[i] = config->wf_offset -
+                       config->wf_amplitude / 2 + 
+                       0.5 * config->wf_amplitude * cos(i * 2 * PI * ratio);
+       }
+}
+
+void a4l_sg_init_sawtooth(struct waveform_config *config, double *values)
+{
+       int i;
+
+       double ratio = config->wf_frequency / config->spl_frequency;
+
+       for (i = 0; i < config->spl_count; i++) {
+               
+               int period_idx = (int)floor(i * ratio);
+
+               values[i] = config->wf_offset -
+                       config->wf_amplitude / 2 -
+                       period_idx * config->wf_amplitude +
+                       i * ratio * config->wf_amplitude;
+       }
+}
+
+void a4l_sg_init_triangular(struct waveform_config *config, double *values)
+{
+       int i;
+
+       double ratio = config->wf_frequency / config->spl_frequency;
+
+       for (i = 0; i < config->spl_count; i++) {
+
+               int period_idx = (int)floor(i * ratio);
+               int half_period_idx = (int)floor(i * 2 * ratio);
+               int rise = ((half_period_idx % 2) == 0) ? 1 : 0;
+
+               if (rise) {
+                       values[i] = config->wf_offset - 
+                               config->wf_amplitude / 2 -
+                               2 * period_idx * config->wf_amplitude +
+                               2 * i * ratio * config->wf_amplitude;
+               } else {
+                       values[i] = config->wf_offset -
+                               config->wf_amplitude / 2 +
+                               2 * (period_idx + 1) * config->wf_amplitude - 
+                               2 * i * ratio * config->wf_amplitude;
+               }
+       }
+}
+
+void a4l_sg_init_steps(struct waveform_config *config, double *values)
+{
+       int i;
+       
+       double ratio = config->wf_frequency / config->spl_frequency;
+       
+       for (i = 0; i < config->spl_count; i++) {
+               int half_period_idx = (int)floor(i * 2 * ratio);
+               int even = (half_period_idx % 2 == 0);
+               
+               values[i] = config->wf_offset - 
+                       config->wf_amplitude / 2 + even * config->wf_amplitude;
+       }
+}
+
+void a4l_sg_set_sample_count(struct waveform_config *config)
+{
+       int sample_count = MIN_SAMPLE_COUNT;
+       int best_count = MIN_SAMPLE_COUNT;
+       double lowest_diff = INFINITY;
+
+       while (sample_count < MAX_SAMPLE_COUNT) {
+
+               double ratio = (double)sample_count * 
+                       (config->wf_frequency / config->spl_frequency);
+               int ceiling = ceil(ratio);
+               double diff = (double)ceiling - ratio;
+
+               assert(diff >= 0);
+
+               if (diff < lowest_diff) {
+                       lowest_diff = diff;
+                       best_count = sample_count;
+               }
+
+               if (diff == 0)
+                       break;
+
+               sample_count++;
+       }
+
+       if (lowest_diff != 0) {
+               printf("Warning: unable to create a contiguous signal\n");
+               printf("Warning: an approximation is performed\n");
+       }
+
+       config->spl_count = best_count;
+}
+
+int a4l_sg_check_config(struct waveform_config *config)
+{
+
+       if (config->wf_amplitude == 0)
+               printf("Warning: the signal will be constant\n");
+
+       if (config->wf_frequency * 2 > config->spl_frequency) {
+               printf("Error: the sampling frequency is not correct\n");
+               printf("Error: sampling frequency >= 2 * signal frequency\n");
+               return -EINVAL;
+       }
+
+       /* TODO: check with find_range */
+       
+       return 0;
+}
+
+static void (* init_values[])(struct waveform_config *, double *) = {
+       a4l_sg_init_sine,
+       a4l_sg_init_sawtooth,
+       a4l_sg_init_triangular,
+       a4l_sg_init_steps,
+};
+
+void a4l_sg_init_values(struct waveform_config *config, double *values)
+{
+       init_values[config->wf_kind](config, values);
+}
+
+void a4l_sg_dump_values(struct waveform_config *config, double *values)
+{
+       int i;
+       
+       for (i = 0; i < config->spl_count; i++)
+               printf("%f\n", values[i]);
+}
+
diff --git a/src/utils/analogy/signal_generation.h 
b/src/utils/analogy/signal_generation.h
new file mode 100644
index 0000000..6f6d2cf
--- /dev/null
+++ b/src/utils/analogy/signal_generation.h
@@ -0,0 +1,38 @@
+#ifndef __SIGNAL_GENERATION_H__
+#define  __SIGNAL_GENERATION_H__
+
+#include <stdio.h>
+
+#include <analogy/analogy.h>
+
+#define MAX_SAMPLE_COUNT 8096
+#define MIN_SAMPLE_COUNT 2
+
+#define WAVEFORM_SINE 0
+#define WAVEFORM_SAWTOOTH 1
+#define WAVEFORM_TRIANGULAR 2
+#define WAVEFORM_STEPS 3
+
+struct waveform_config {
+       
+       /* Waveform stuff */
+       int wf_kind;
+       double wf_frequency;
+       double wf_amplitude;
+       double wf_offset;
+
+       /* Sampling stuff */
+       double spl_frequency;
+       int spl_count;
+};
+
+void a4l_sg_init_sine(struct waveform_config *config, double *values);
+void a4l_sg_init_sawtooth(struct waveform_config *config, double *values);
+void a4l_sg_init_triangular(struct waveform_config *config, double *values);
+void a4l_sg_init_steps(struct waveform_config *config, double *values);
+void a4l_sg_set_sample_count(struct waveform_config *config);
+int a4l_sg_check_config(struct waveform_config *config);
+void a4l_sg_init_values(struct waveform_config *config, double *values);
+void a4l_sg_dump_values(struct waveform_config *config, double *values);
+
+#endif /*  __SIGNAL_GENERATION_H__ */


_______________________________________________
Xenomai-git mailing list
Xenomai-git@gna.org
https://mail.gna.org/listinfo/xenomai-git

Reply via email to