2 * Asynchronous Analog Output Example
5 * Copyright (c) 1999,2000 David A. Schleef <ds@schleef.org>
6 * Copyright (c) 2005 Frank Mori Hess <fmhess@@users.sourceforge.net>
8 * This file may be freely modified, distributed, and combined with
9 * other software, as long as proper attribution is given in the
14 * Requirements: Analog output device capable of
15 * asynchronous commands.
17 * This demo uses an analog output subdevice with an
18 * asynchronous command to generate a waveform. The
19 * waveform in this example is a sine wave (surprise!).
20 * The waveform data is passed to comedi through
21 * a memory mapping (as opposed to using write()).
22 * The entire buffer is filled once with one period
27 #include <comedilib.h>
40 static int comedi_internal_trigger(comedi_t *dev, unsigned int subd, unsigned int trignum)
45 memset(&insn, 0, sizeof(comedi_insn));
46 insn.insn = INSN_INTTRIG;
53 return comedi_do_insn(dev, &insn);
56 static void write_waveform(sampl_t *buffer, int size, double amplitude, double offset, int maxdata)
60 for(i = 0; i < size; ++i)
62 double temp = (amplitude / 2.) * sin((2. * M_PI * i) / size) + offset;
63 if(temp < 0.) temp = 0.;
64 if(temp > maxdata) temp = maxdata;
65 buffer[i] = (sampl_t)temp;
69 int main(int argc, char *argv[])
76 unsigned int chanlist[16];
82 /* peak-to-peak amplitude, in DAC units (i.e., 0-4095) */
84 /* offset, in DAC units */
89 parse_options(argc,argv);
91 /* Force n_chan to be 1 */
94 dev = comedi_open(filename);
96 fprintf(stderr, "error opening %s\n", filename);
99 subdevice = comedi_find_subdevice_by_type(dev,COMEDI_SUBD_AO,0);
101 maxdata = comedi_get_maxdata(dev,subdevice,0);
102 rng = comedi_get_range(dev,subdevice,0,0);
104 offset = (double)comedi_from_phys(0.0, rng, maxdata);
105 amplitude = (double)comedi_from_phys(1.0, rng, maxdata) - offset;
107 memset(&cmd,0,sizeof(cmd));
108 cmd.subdev = subdevice;
110 cmd.start_src = TRIG_INT;
112 cmd.scan_begin_src = TRIG_TIMER;
113 cmd.scan_begin_arg = 1e9/freq;
114 cmd.convert_src = TRIG_NOW;
116 cmd.scan_end_src = TRIG_COUNT;
117 cmd.scan_end_arg = n_chan;
118 cmd.stop_src = TRIG_NONE;
121 cmd.chanlist = chanlist;
122 cmd.chanlist_len = n_chan;
124 chanlist[0] = CR_PACK(channel,range,aref);
126 dump_cmd(stdout,&cmd);
128 err = comedi_command_test(dev, &cmd);
130 comedi_perror("comedi_command_test");
134 err = comedi_command_test(dev, &cmd);
136 comedi_perror("comedi_command_test");
140 if ((err = comedi_command(dev, &cmd)) < 0) {
141 comedi_perror("comedi_command");
145 size = comedi_get_buffer_size(dev, subdevice);
146 fprintf(stderr, "buffer size is %d\n", size);
147 map = mmap(NULL, size, PROT_WRITE, MAP_SHARED, comedi_fileno(dev), 0);
148 if(map == MAP_FAILED)
153 write_waveform(map, size, amplitude, offset, maxdata);
154 if(msync(map, size, MS_SYNC) < 0)
159 ret = comedi_internal_trigger(dev, subdevice, 0);
161 comedi_perror("comedi_internal_trigger\n");
165 int bytes_marked = comedi_get_buffer_contents(dev,subdevice);
168 comedi_perror("comedi_get_buffer_contents");
171 int bytes_unmarked = size - bytes_marked;
172 // this keeps comedi from reporting a buffer underrun
173 if(comedi_mark_buffer_written(dev, subdevice, bytes_unmarked) < 0)
175 comedi_perror("comedi_mark_buffer_written");