Version 0.8.x will feature a replacement for the comedi_trig structure that allows much more flexible acquisition with applicable hardware. Gone will be the days of "mode2" and friends. The replacement for mode0, i.e., immediate acquisition, is a new ioctl that is very similar to the old trigger ioctl, but just implements mode0 features. The other modes are replaced by the comedi "command" ioctl. The command structure allows you to specify what causes each action that is taken during acquisition. The actions currently understood by comedi are: - Start acquisition - Stop acquisition - Begin a scan - End a scan - Convert a sample A "scan" is a repeated measurement of N different channels. The different types of "triggers" or "trigger signals" that can cause events to occur are: - TRIG_NONE - don't ever trigger - TRIG_NOW - cause trigger to occur right now (or really soon) - TRIG_FOLLOW - (see below) - TRIG_TIME - trigger at specific time - TRIG_TIMER - trigger at specific rate - TRIG_COUNT - trigger when count reaches specific value - TRIG_EXT - trigger on external signal - TRIG_INT - trigger on an internal comedi signal Not all triggers are applicable to all events. Supported triggers for specific events depends significantly on your particular device. In addition, for every trigger type, there is a cooresponding argument that specifies the rate, the count, which external signal, etc. In particular, scan_end events will almost always be triggered on TRIG_COUNT, with the argument being the number of channels in the scan. (Actually, samples in the scan, since on most boards you can measure a single channel multiple times in a scan.) Also, until otherwise supported, start events can only be TRIG_NOW. TRIG_FOLLOW is a special type of trigger for scan_begin events that triggers on the next lower level trigger, in this case, the trigger for convert events. It may or may not be supported. Later, it may also be used for start events if you want to chain multiple commands. I might also consider using it for convert events, to indicate the board maximum rate. The command strucure is as follows: struct comedi_cmd_struct{ unsigned int subdev; unsigned int flags; unsigned int start_src; unsigned int start_arg; unsigned int scan_begin_src; unsigned int scan_begin_arg; unsigned int convert_src; unsigned int convert_arg; unsigned int scan_end_src; unsigned int scan_end_arg; unsigned int stop_src; unsigned int stop_arg; unsigned int *chanlist; /* channel/range list */ unsigned int chanlist_len; sampl_t *data; /* data list, size depends on subd flags */ unsigned int data_len; }; subdev is the target subdevice. flags are flags, similar to the old trigger structure. chanlist, chanlist_len, data, and data_len are similar to the old trigger structure, although chanlist_len has been changed from n_chan. data and data_len are used only by users who write kernel-space code, i.e., virtual comedi devices or RTLinux. Some examples for commands: Suppose you want to measure channels 1,2,3,4 at a rate of 10 khz, with the inter-sample time at 10 us (100 khz), and that you want to measure 10000 scans. This is analogous to the old mode2 acquisition. Initialization of the command structure to do this would include: start_src = TRIG_NOW; start_arg = 0; // doesn't matter scan_begin_src = TRIG_TIMER; scan_begin_arg = 100000; // == 100e3 nanoseconds convert_src = TRIG_TIMER; convert_arg = 10000; // == 10e3 nanoseconds scan_end_src = TRIG_COUNTER; scan_end_arg = 4; // == number of channels stop_src = TRIG_COUNTER; stop_arg = 10000; // == 10000 scans If, instead, you wish to start continuous acquisition, and stop it with a comedi_cancel(), you would change the stop event trigger to: stop_src = TRIG_NONE; stop_arg = 0; Suppose you want to use an external signal to trigger scan_begin events. Then you would change the scan_begin event trigger to: scan_begin_src = TRIG_EXT; scan_begin_arg = 2; // external trigger #2 The number of possible external trigger lines is board dependent. Your board may only have one non-configurable digital external trigger, or it may support complicated selection of external triggering, including analog triggers at multiple levels, edge or level digital triggers, synchonization signals with other boards, etc. Eventually, boards that support complicated triggering will have a triggering subdevice with which you can configure all the different features. Here's some pseudo-code that describes how the device should interpret your command: do_command() { while(!start_trigger) do_nothing(); while(!stop_trigger){ if(!scan_begin_trigger) continue; while(!scan_end_trigger){ while(!convert_trigger) do_nothing(); do_conversion(); } } } The fencepost issues, i.e., what happens when you have conflicting triggers, is device-dependent.