NAME

dmaad -- DMA analog-to-digital converter user routines

SYNOPSIS

#include <dmaad_u.h>
#include <signal_p.h>

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;

DESCRIPTION

The Direct-Memory-Access analog-to-digital (DMA A/D) subroutines control a Data Translation DT3362, an 8 channel, 12-bit analog-to-digital converter designed for high-speed data acquisition. Two subroutine interfaces are provided. dadset and its associated macros( dadbeg , dadxbeg , dadxend , dadcount , dadbufptr , and daddone ) control the conversion of multiple samples using DMA transfer; dadread reads a single sample under program control.

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).

EXAMPLE

/*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;
}
}

FILES

/dev/dad0

DIAGNOSTICS

dadset returns a -1 if any of its arguments are invalid: nchan is less than 0 or greater than 256, a channel number is not between 1 and 8 or bufl is NULL. The DMA A/D sends the signal SIGDADERR on overrun or other device errors.

SEE ALSO

dmaad(4F) , dmada(3U) , signal(2F) , atod(3U).