- From: Jim Benson <jbenson_at_sextans.lowell.edu>
- Date: Fri, 8 Nov 2002 17:56:00 -0700 (MST)
Hi,
I am just starting to play with comedi...here is the driver info:
cat /proc/comedi
comedi version 0.7.65
format string: "%2d: %-20s %-20s
%4d",i,driver_name,board_name,n_subdevices
0: ni_atmio at-mio-16e-1 8
ni_atmio:
ni_atmio
8255:
8255
I included some test code below...modified versions of some of the
examples.
I have 2 questions:
When i have:
/* The end of acquisition is controlled by stop_src and
* stop_arg.
* TRIG_COUNT: stop acquisition after stop_arg scans.
* TRIG_NONE: continuous acquisition, until stopped using
* comedi_cancel()
* */
cmd->stop_src = TRIG_COUNT;
cmd->stop_arg = iNumScans;
the following:
for (i=0; i<45; i++) {
iNumAvailBytes = comedi_get_buffer_contents(dev, iSubDevice);
printf("i iNumAvailBytes: %d\t%d\n", i, iNumAvailBytes);
usleep(250000);
}
shows zero iNumAvailBytes until the 10 requested scans are finished....
then 40 bytes (correct for 2 channels).
I was expecting to see the iNumAvailBytes increase as the scan
went along. What am i missing here?
The second questions is that when i change to TRIG_NONE:
/* The end of acquisition is controlled by stop_src and
* stop_arg.
* TRIG_COUNT: stop acquisition after stop_arg scans.
* TRIG_NONE: continuous acquisition, until stopped using
* comedi_cancel()
* */
cmd->stop_src = TRIG_NONE;
cmd->stop_arg = 0;
iNumAvailBytes is then always zero...which seems to suggest
to me that the continious scan mode never started.
What am i doing wrong here?
Thanks,
Jim
#define N_CHANNELS_TO_SAMPLE 2
unsigned int uChannelList[N_CHANNELS_TO_SAMPLE];
int iHz = 1;
int iNumScans = 10;
int iNumChannels = N_CHANNELS_TO_SAMPLE;
int prepare_cmd(comedi_t *dev,int subdevice,comedi_cmd *cmd);
int main(int argc, char **argv) {
comedi_t *dev;
comedi_range *pComediRange;
comedi_cmd comediCmd;
comedi_cmd *pComediCmd;
lsampl_t lsMaxData, lsData;
int iSubDevice=0, iChannel=0, iRange=0,
iARef=AREF_GROUND;
int i, iRet, iStreamingBufferSize, iBufferOffset, iNumAvailBytes;
double dMinVolts, dMaxVolts, dVolts;
pComediCmd = &comediCmd;
dev = comedi_open("/dev/comedi0");
lsMaxData = comedi_get_maxdata(dev, iSubDevice, iChannel);
printf("\nlsMaxData = %d", lsMaxData);
pComediRange = comedi_get_range(dev, iSubDevice, iChannel, iRange);
//comedi_data_read(dev, iSubDevice, iChannel, iRange, iARef, &lsData);
// Bug in comedi_to_phys ?: Returns NAN for 0 and lsMaxData
dMaxVolts = comedi_to_phys(lsMaxData-1, pComediRange, lsMaxData);
dMinVolts = comedi_to_phys(1, pComediRange, lsMaxData);
iStreamingBufferSize = comedi_get_buffer_size(dev, iSubDevice);
printf("\niStreamingBufferSize: %d", iStreamingBufferSize);
// Do the memory map.
map = mmap(NULL, iStreamingBufferSize, PROT_READ, MAP_SHARED,
comedi_fileno(dev),0);
printf("\nmap = %p", map);
for (i=0; i<iNumChannels; i++) {
uChannelList[i] = CR_PACK(i, iRange, iARef);
}
prepare_cmd(dev, iSubDevice, pComediCmd);
iRet = comedi_command_test(dev, pComediCmd);
iRet = comedi_command_test(dev, pComediCmd);
if (iRet != 0) {
printf("\ncomedi_command_test failed.");
}
else {
printf("\ncomedi_command_test successful.");
}
// Send the command.
iRet = comedi_command(dev, pComediCmd);
if (iRet < 0) {
printf("\nERROR: comedi_command failed.");
printf("\n");
exit(1);
}
printf("\nStarting loop.");
printf("\n");
for (i=0; i<45; i++) {
//iBufferOffset = comedi_get_buffer_offset(dev, iSubDevice);
iNumAvailBytes = comedi_get_buffer_contents(dev, iSubDevice);
// printf("i iBufferOffset: %d\t%d\n", i, iBufferOffset);
printf("i iNumAvailBytes: %d\t%d\n", i, iNumAvailBytes);
usleep(250000);
}
comedi_cancel(dev, iSubDevice);
for (i=0; i<45; i++) {
iNumAvailBytes = comedi_get_buffer_contents(dev, iSubDevice);
printf("i iNumAvailBytes: %d\t%d\n", i, iNumAvailBytes);
usleep(250000);
}
printf("\n");
printf("\nAll Done.");
printf("\n");
// comedi_close(dev);
return 0;
}
/*
* Set up a command by hand. This will not work on some devices.
* There is no single command that will work on all devices.
*/
int prepare_cmd(comedi_t *dev,int iSubDevice, comedi_cmd *cmd) {
memset(cmd,0,sizeof(*cmd));
/* the subdevice that the command is sent to */
cmd->subdev = iSubDevice;
/* flags */
cmd->flags = 0;
/* Wake up at the end of every scan */
//cmd->flags |= TRIG_WAKE_EOS;
/* Use a real-time interrupt, if available */
//cmd->flags |= TRIG_RT;
/* each event requires a trigger, which is specified
by a source and an argument. For example, to specify
an external digital line 3 as a source, you would use
src=TRIG_EXT and arg=3. */
/* The start of acquisition is controlled by start_src.
* TRIG_NOW: The start_src event occurs start_arg nanoseconds
* after comedi_command() is called. Currently,
* only start_arg=0 is supported.
* TRIG_FOLLOW: (For an output device.) The start_src event occurs
* when data is written to the buffer.
* TRIG_EXT: start event occurs when an external trigger
* signal occurs, e.g., a rising edge of a digital
* line. start_arg chooses the particular digital
* line.
* TRIG_INT: start event occurs on a Comedi internal signal,
* which is typically caused by an INSN_TRIG
* instruction.
*/
cmd->start_src = TRIG_NOW;
cmd->start_arg = 0;
/* The timing of the beginning of each scan is controlled by
* scan_begin.
* TRIG_TIMER: scan_begin events occur periodically.
* The time between scan_begin events is
* convert_arg nanoseconds.
* TRIG_EXT: scan_begin events occur when an external trigger
* signal occurs, e.g., a rising edge of a digital
* line. scan_begin_arg chooses the particular digital
* line.
* TRIG_FOLLOW: scan_begin events occur immediately after a scan_end
* event occurs.
* The scan_begin_arg that we use here may not be supported exactly
* by the device, but it will be adjusted to the nearest supported
* value by comedi_command_test(). */
cmd->scan_begin_src = TRIG_TIMER;
cmd->scan_begin_arg = 1e9/iHz; /* in ns */
/* The timing between each sample in a scan is controlled by convert.
* TRIG_TIMER: Conversion events occur periodically.
* The time between convert events is
* convert_arg nanoseconds.
* TRIG_EXT: Conversion events occur when an external trigger
* signal occurs, e.g., a rising edge of a digital
* line. convert_arg chooses the particular digital
* line.
* TRIG_NOW: All conversion events in a scan occur simultaneously.
* Even though it is invalid, we specify 1 ns here. It will be
* adjusted later to a valid value by comedi_command_test() */
cmd->convert_src = TRIG_TIMER;
cmd->convert_arg = 1; /* in ns */
/* The end of each scan is almost always specified using
* TRIG_COUNT, with the argument being the same as the
* number of channels in the chanlist. You could probably
* find a device that allows something else, but it would
* be strange. */
cmd->scan_end_src = TRIG_COUNT;
cmd->scan_end_arg = iNumChannels; /* number of channels */
/* The end of acquisition is controlled by stop_src and
* stop_arg.
* TRIG_COUNT: stop acquisition after stop_arg scans.
* TRIG_NONE: continuous acquisition, until stopped using
* comedi_cancel()
* */
cmd->stop_src = TRIG_NONE; // TRIG_COUNT
cmd->stop_arg = 0; //iNumScans;
/* the channel list determined which channels are sampled.
In general, chanlist_len is the same as scan_end_arg. Most
boards require this. */
cmd->chanlist = uChannelList;
cmd->chanlist_len = iNumChannels;
return 0;
}
Received on 2002-11-09Z00:56:00