dadset (nsamp, nchan, chan, buf1, buf2);
int nsamp, nchan, *chan, *buf1, *buf2;
dadbeg;
dadxbeg;
dadxend;
daddone;
dadcount;
dadbufptr;
dadread (chan, samp);
int chan, *samp;
extern int dadfull;
Multiple Sampling
The multiple sampling routines collect one or more
samples from one or more channels using a DMA transfer scheme.
Because samples are stored under hardware control, samples can be
collected at high rates, and the user's program is free to do other
tasks during the sampling operation. An option is provided for double
buffering.
To use the DMA A/D for multiple sampling, the user specifies a list of channels and the number of conversions to perform for each channel in the list. With each conversion cycle, one sample from each specified channel is collected and stored in a user-supplied buffer. A conversion cycle is triggered either by a command from the program or by a pulse from an external oscillator. The maximum sampling rate of the DMA A/D is 50 kHz. If, for example, the external oscillator is set at 9.8 kHz, the device can sample up to 5, but not 6 or more, channels per cycle.
dadset initializes the DMA A/D for multiple sampling. nchan is the number of channels (up to 256) to sample in each cycle. The channels are specified in the array pointed to by chan. Legal channel numbers are 1 through 8. nsamp specifies the number of samples to collect each channel, which is also the number of conversion cycles. The total number of samples collected will equal nchan*nsamp.
buf1 points to the buffer in which the samples will be stored and should be of length nsamp*nchan.
buf2 points to a second buffer for double bufferind (described below). If the double buffering feature is not used, buf2 should equal NULL.
dadbeg starts one conversion cycle. After one sample is taken from each specified channel, the device waits for the next trigger. dadxbeg enables an external oscillator to trigger conversions. With each pulse, the DMA A/D performs one conversion cycle, i.e., converts one sample for each specified channel. dadxend disables the external oscillator.
daddone is tested to determine when all nchan*nsamp conversions are done, returning a non zero integer to indicate completion. Alternatively, the user program may arrange to catch the software signal SIGDAD (that indicates completion) by calling signal (see signal(2F) ) after dadset but before the conversion process begins. The arguments passed to the signal catching routine are the signal number, a file descriptor for the device, and the address of the buffer just filled.
The macros dadbufptr and dadcount provide status information on the DMA A/D operation. Dadcount tells how many samples remain. Dadbufptr points to the next location in the user buffer to be filled.
For double buffering, the user calls dadxbeg to begin filling the first buffer. Then while thee user program processes the first buffer, the second buffer is filled. The two buffers continue to be filled and processed, alternately, until dadxend is invoked. SIGDAD is sent after filling each buffer. To synchronize double buffering, the expternal variant dadfull declared in <dmaad_u.h> is used. After the DMA A/D fills a buffer it increments dadfull. Therefore, before processing a buffer, the user must wait until one is ready by checking for dadfull greater than 0. After processing a buffer, the user program must decrement dadfull to indicate that another buffer is available for filling. The user must also keep track of which buffer to process next. The rate of processing in the user program must be faster than the conversion rate, otherwise the signal SIGDADERR is generated and sampling stops. The signal is sent along with a decixe file descriptor and the current buffer address.
Single Sampling
The
dadread
subroutine reads a single sample from one channel (
chan
) into
samp.
Since the DT3362 is oriented toward DMA operations, dadread, a
non-DMA operation is less efficient than the single sample A/D read
routine
adread
described in
atod(3U).
/*DMA AD test: single buffer, multiple channels and samples */ #include <stdio_p.h> #include <signal_p.h> #include <dmaad_u.h> #define NSAMP 1000 #define NCHAN 4 int *buf1, done = 0, donesig(); int channel[NCHAN]= {1,2,3,4}; main() { buf1 = (int *)malloc(NSAMP*NCHAN*sizeof(int); if(dadset (NSAMP, NCHAN, channel, buf1, (int *)NULL == -1) errexit(1, "dadset error\n"); signal(SIGDAD, donesig); dadxbeg; while(done == 0){ ... /* do other user tasks */ } } donesig(sig, fd, val) int sig, val; FD fd; { ... /* do processing that must be done as soon as sampling completes */ done++; } /* DMA A/D test: double buffer, multiple channels and samples */ #include <stdio_p.h> #include <dmaad_u.h> #define NCHAN 8 #define NSAMP 5120 #define NBUFS 50 int channel[NCHAN]; int samp1[NSAMP], samp2[NSAMP]; main() { register int wbufcnt; /* count buffers */ if (dadset(NSAMP, NCHAN, channel, samp1, samp2) == -1) errexit(1,"dadset error\n"); wbufcnt = 0; dadxbeg; for(;;){ while(dadfull == 0) ; /* process first buffer */ if(++wbufcnt == NBUFS){ dadxend; break; } --dadfull; while(dadfull == 0) ; /* process second buffer */ if(++wbufcnt == NBUFS){ dadxend; break; } --dadfull; } }