info is board_info now
[comedilib.git] / demo / select.c
1 /*
2  * selet.c - Example of using select() with Comedi
3  * Part of Comedilib
4  *
5  * Copyright (c) 1999,2000 David A. Schleef <ds@schleef.org>
6  *
7  * This file may be freely modified, distributed, and combined with
8  * other software, as long as proper attribution is given in the
9  * source code.
10  */
11
12 /*
13  * An example for using select() with asynchronous input.  This
14  * example requires an asynchronous input subdevice that can
15  * handle TRIG_TIMER as a scan_begin_src.
16  */
17
18 #include <stdio.h>
19 #include <comedilib.h>
20 #include <fcntl.h>
21 #include <unistd.h>
22 #include <stdlib.h>
23 #include <errno.h>
24 #include <getopt.h>
25 #include <ctype.h>
26 #include <string.h>
27 #include <sys/time.h>
28 #include "examples.h"
29
30 #define N_SCANS         10
31 #define N_CHANS         16
32
33 #define BUFSZ 1000
34 sampl_t buf[BUFSZ];
35
36 int n_chans = 1;
37 int n_scans = 10;
38
39 unsigned int chanlist[4];
40
41 comedi_t *device;
42
43 void prepare_cmd(comedi_t *dev,comedi_cmd *cmd);
44 void do_cmd(comedi_t *dev,comedi_cmd *cmd);
45
46 #define sec_to_nsec(x) ((x)*1000000000)
47 #define sec_to_usec(x) ((x)*1000000)
48 #define sec_to_msec(x) ((x)*1000)
49 #define msec_to_nsec(x) ((x)*1000000)
50 #define msec_to_usec(x) ((x)*1000)
51 #define usec_to_nsec(x) ((x)*1000)
52
53 int main(int argc, char *argv[])
54 {
55         comedi_cmd cmd;
56         int i;
57
58         parse_options(argc,argv);
59
60         device = comedi_open(filename);
61         if(!device){
62                 perror(filename);
63                 exit(1);
64         }
65
66         fcntl(comedi_fileno(device),F_SETFL,O_NONBLOCK);
67
68         for(i=0;i<n_chans;i++){
69                 chanlist[i]=CR_PACK(channel+i,range,aref);
70         }
71
72         prepare_cmd(device,&cmd);
73
74         do_cmd(device,&cmd);
75
76         return 0;
77 }
78
79 void do_cmd(comedi_t *dev,comedi_cmd *cmd)
80 {
81         int total=0;
82         int ret;
83         int go;
84         fd_set rdset;
85         struct timeval timeout;
86
87         ret=comedi_command_test(dev,cmd);
88
89         printf("test ret=%d\n",ret);
90         if(ret<0){
91                 printf("errno=%d\n",errno);
92                 comedi_perror("comedi_command_test");
93                 return;
94         }
95
96         dump_cmd(stdout,cmd);
97
98         ret=comedi_command_test(dev,cmd);
99
100         printf("test ret=%d\n",ret);
101         if(ret<0){
102                 printf("errno=%d\n",errno);
103                 comedi_perror("comedi_command_test");
104                 return;
105         }
106
107         dump_cmd(stdout,cmd);
108
109         ret=comedi_command(dev,cmd);
110
111         printf("ret=%d\n",ret);
112         if(ret<0){
113                 printf("errno=%d\n",errno);
114                 comedi_perror("comedi_command");
115                 return;
116         }
117
118         go=1;
119         while(go){
120                 FD_ZERO(&rdset);
121                 FD_SET(comedi_fileno(device),&rdset);
122                 timeout.tv_sec = 0;
123                 timeout.tv_usec = 50000;
124                 ret = select(comedi_fileno(dev)+1,&rdset,NULL,NULL,&timeout);
125                 printf("select returned %d\n",ret);
126                 if(ret<0){
127                         perror("select");
128                 }else if(ret==0){
129                         /* hit timeout */
130                         printf("timeout\n");
131                 }else if(FD_ISSET(comedi_fileno(device),&rdset)){
132                         /* comedi file descriptor became ready */
133                         printf("comedi file descriptor ready\n");
134                         ret=read(comedi_fileno(dev),buf,sizeof(buf));
135                         printf("read returned %d\n",ret);
136                         if(ret<0){
137                                 if(errno==EAGAIN){
138                                         go = 0;
139                                         perror("read");
140                                 }
141                         }else if(ret==0){
142                                 go = 0;
143                         }else{
144                                 int i;
145                                 total+=ret;
146                                 //printf("read %d %d\n",ret,total);
147                                 for(i=0;i<ret/sizeof(sampl_t);i++){
148                                         printf("%d\n",buf[i]);
149                                 }
150                         }
151                 }else{
152                         /* unknown file descriptor became ready */
153                         printf("unknown file descriptor ready\n");
154                 }
155         }
156 }
157
158 /*
159  * This part of the demo measures channels 1, 2, 3, 4 at a rate of
160  * 10 khz, with the inter-sample time at 10 us (100 khz).  The number
161  * of scans measured is 10.  This is analogous to the old mode2
162  * acquisition.
163  */
164 void prepare_cmd(comedi_t *dev,comedi_cmd *cmd)
165 {
166         memset(cmd,0,sizeof(*cmd));
167
168         /* the subdevice that the command is sent to */
169         cmd->subdev =   subdevice;
170
171         /* flags */
172         cmd->flags =    TRIG_WAKE_EOS;
173         //cmd.flags =   0;
174
175         /* each event requires a trigger, which is specified
176            by a source and an argument.  For example, to specify
177            an external digital line 3 as a source, you would use
178            src=TRIG_EXT and arg=3. */
179
180         /* In this case, we specify using TRIG_NOW to start
181          * acquisition immediately when the command is issued.  
182          * The argument of TRIG_NOW is "number of nsec after
183          * NOW", but no driver supports it yet.  Also, no driver
184          * currently supports using a start_src other than
185          * TRIG_NOW.  */
186         cmd->start_src =                TRIG_NOW;
187         cmd->start_arg =                0;
188
189         /* The timing of the beginning of each scan is controlled
190          * by scan_begin.  TRIG_TIMER specifies that scan_start
191          * events occur periodically at a rate of scan_begin_arg
192          * nanoseconds between scans. */
193         cmd->scan_begin_src =   TRIG_TIMER;
194         cmd->scan_begin_arg =   msec_to_nsec(100);
195
196         /* The timing between each sample in a scan is controlled
197          * by convert.  Like above, TRIG_TIMER specifies that
198          * convert events occur periodically at a rate of convert_arg
199          * nanoseconds between scans. */
200         cmd->convert_src =      TRIG_TIMER;
201         cmd->convert_arg =      msec_to_nsec(1);
202
203         /* The end of each scan is almost always specified using
204          * TRIG_COUNT, with the argument being the same as the
205          * number of channels in the chanlist.  You could probably
206          * find a device that allows something else, but it would
207          * be strange. */
208         cmd->scan_end_src =     TRIG_COUNT;
209         cmd->scan_end_arg =     n_chans;        /* number of channels */
210
211         /* The end of acquisition is controlled by stop_src and
212          * stop_arg.  The src will typically be TRIG_COUNT or
213          * TRIG_NONE.  Specifying TRIG_COUNT will stop acquisition
214          * after stop_arg number of scans, or TRIG_NONE will
215          * cause acquisition to continue until stopped using
216          * comedi_cancel(). */
217         cmd->stop_src =         TRIG_COUNT;
218         cmd->stop_arg =         n_scans;
219
220         /* the channel list determined which channels are sampled.
221            In general, chanlist_len is the same as scan_end_arg.  Most
222            boards require this.  */
223         cmd->chanlist =         chanlist;
224         cmd->chanlist_len =     n_chans;
225 }
226