added memory mapped ao waveform demo (untested)
authorFrank Mori Hess <fmhess@speakeasy.net>
Mon, 17 Jan 2005 20:20:26 +0000 (20:20 +0000)
committerFrank Mori Hess <fmhess@speakeasy.net>
Mon, 17 Jan 2005 20:20:26 +0000 (20:20 +0000)
demo/Makefile.am
demo/ao_mmap.c [new file with mode: 0644]

index c1d86748ec4d44d565c3867967f60394cf9aa810..1070826056989928abf3623014c74acac51470f6 100644 (file)
@@ -1,6 +1,6 @@
 
 noinst_PROGRAMS = \
-       antialias ao_waveform apply_cal cmd dio eeprom_dump info \
+       antialias ao_waveform ao_mmap apply_cal cmd dio eeprom_dump info \
        inp inpn insn ledclock mmap outp poll receiver select \
        sender sigio sv tut1 tut2
 
@@ -14,6 +14,10 @@ ao_waveform_SOURCES = ao_waveform.c common.c
 ao_waveform_CFLAGS = $(COMEDILIB_CFLAGS)
 ao_waveform_LDADD = $(COMEDILIB_LIBS)
 
+ao_mmap_SOURCES = ao_mmap.c common.c
+ao_mmap_CFLAGS = $(COMEDILIB_CFLAGS)
+ao_mmap_LDADD = $(COMEDILIB_LIBS)
+
 apply_cal_SOURCES = apply_cal.c common.c
 apply_cal_CFLAGS = $(COMEDILIB_CFLAGS)
 apply_cal_LDADD = $(COMEDILIB_LIBS)
diff --git a/demo/ao_mmap.c b/demo/ao_mmap.c
new file mode 100644 (file)
index 0000000..82493e0
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ * Asynchronous Analog Output Example
+ * Part of Comedilib
+ *
+ * Copyright (c) 1999,2000 David A. Schleef <ds@schleef.org>
+ * Copyright (c) 2005 Frank Mori Hess <fmhess@@users.sourceforge.net>
+ *
+ * This file may be freely modified, distributed, and combined with
+ * other software, as long as proper attribution is given in the
+ * source code.
+ */
+
+/*
+ * Requirements: Analog output device capable of
+ *    asynchronous commands.
+ *
+ * This demo uses an analog output subdevice with an
+ * asynchronous command to generate a waveform.  The
+ * waveform in this example is a sine wave (surprise!).
+ * The waveform data is passed to comedi through
+ * a memory mapping (as opposed to using write()).
+ * The entire buffer is filled once with one period
+ * of the waveform.
+ */
+
+#include <stdio.h>
+#include <comedilib.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <getopt.h>
+#include <ctype.h>
+#include <math.h>
+#include <string.h>
+#include <sys/mman.h>
+#include "examples.h"
+
+
+static int comedi_internal_trigger(comedi_t *dev, unsigned int subd, unsigned int trignum)
+{
+       comedi_insn insn;
+       lsampl_t data[1];
+
+       memset(&insn, 0, sizeof(comedi_insn));
+       insn.insn = INSN_INTTRIG;
+       insn.subdev = subd;
+       insn.data = data;
+       insn.n = 1;
+
+       data[0] = trignum;
+
+       return comedi_do_insn(dev, &insn);
+}
+
+static void write_waveform(sampl_t *buffer, int size, double amplitude, double offset, int maxdata)
+{
+       int i;
+       
+       for(i = 0; i < size; ++i)
+       {
+               double temp = (amplitude / 2.) * sin((2. * M_PI * i) / size) + offset;
+               if(temp < 0.) temp = 0.;
+               if(temp > maxdata) temp = maxdata;
+               buffer[i] = (sampl_t)temp;
+       }
+}
+
+int main(int argc, char *argv[])
+{
+       comedi_cmd cmd;
+       int err;
+       int n,m;
+       int total=0;
+       comedi_t *dev;
+       unsigned int chanlist[16];
+       unsigned int maxdata;
+       comedi_range *rng;
+       int ret;
+       int size;
+       sampl_t *map;
+       /* peak-to-peak amplitude, in DAC units (i.e., 0-4095) */
+       double amplitude;
+       /* offset, in DAC units */
+       double offset;
+       int subdevice;
+
+       
+       parse_options(argc,argv);
+
+       /* Force n_chan to be 1 */
+       n_chan = 1;
+
+       dev = comedi_open(filename);
+       if(dev == NULL){
+               fprintf(stderr, "error opening %s\n", filename);
+               return -1;
+       }
+       subdevice = comedi_find_subdevice_by_type(dev,COMEDI_SUBD_AO,0);
+
+       maxdata = comedi_get_maxdata(dev,subdevice,0);
+       rng = comedi_get_range(dev,subdevice,0,0);
+
+       offset = (double)comedi_from_phys(0.0, rng, maxdata);
+       amplitude = (double)comedi_from_phys(1.0, rng, maxdata) - offset;
+
+       memset(&cmd,0,sizeof(cmd));
+       cmd.subdev = subdevice;
+       cmd.flags = 0;
+       cmd.start_src = TRIG_INT;
+       cmd.start_arg = 0;
+       cmd.scan_begin_src = TRIG_TIMER;
+       cmd.scan_begin_arg = 1e9/freq;
+       cmd.convert_src = TRIG_NOW;
+       cmd.convert_arg = 0;
+       cmd.scan_end_src = TRIG_COUNT;
+       cmd.scan_end_arg = n_chan;
+       cmd.stop_src = TRIG_NONE;
+       cmd.stop_arg = 0;
+
+       cmd.chanlist = chanlist;
+       cmd.chanlist_len = n_chan;
+
+       chanlist[0] = CR_PACK(channel,range,aref);
+
+       dump_cmd(stdout,&cmd);
+
+       err = comedi_command_test(dev, &cmd);
+       if (err < 0) {
+               comedi_perror("comedi_command_test");
+               exit(1);
+       }
+
+       err = comedi_command_test(dev, &cmd);
+       if (err < 0) {
+               comedi_perror("comedi_command_test");
+               exit(1);
+       }
+
+       if ((err = comedi_command(dev, &cmd)) < 0) {
+               comedi_perror("comedi_command");
+               exit(1);
+       }
+       
+       size = comedi_get_buffer_size(dev, subdevice);
+       fprintf(stderr, "buffer size is %d\n", size);
+       map = mmap(NULL, size, PROT_WRITE, MAP_SHARED, comedi_fileno(dev), 0);
+       if(map == MAP_FAILED)
+       {
+               perror("mmap");
+               exit(1);
+       }
+       write_waveform(map, size, amplitude, offset, maxdata);
+       if(msync(map, size, MS_SYNC) < 0)
+       {
+               perror("msync");
+               exit(1);
+       }
+       ret = comedi_internal_trigger(dev, subdevice, 0);
+       if(ret<0){
+               comedi_perror("comedi_internal_trigger\n");
+               exit(1);
+       }
+       while(1){
+               int bytes_marked = comedi_get_buffer_contents(dev,subdevice);
+               if(bytes_marked < 1)
+               {
+                       comedi_perror("comedi_get_buffer_contents");
+                       exit(1);
+               }
+               int bytes_unmarked = size - bytes_marked;
+               // this keeps comedi from reporting a buffer underrun
+               if(comedi_mark_buffer_written(dev, subdevice, bytes_unmarked) < 0)
+               {
+                       comedi_perror("comedi_mark_buffer_written");
+                       exit(1);
+               }
+       }
+       return 0;
+}
+