dmada - DMA digital-to-analog converter user routines


#include <dmada_u.h>
#include <signal_u.h>

int ddaset(nsamp, buf1, buf2);
int nsamp;
unsigned *buf1, *buf2;

int ddapnt (npnts, buf1, buf2);
int npnts;
unsigned *buf1, *buf2;




ddawrite (chan, dval);
int chan, dval;

extern int ddafull;


Subroutines for digital to analog convertion using direct memory asccess (DMA D/A) control a Data Translation DT2771. This is a 2 channel, 12-bit digital to analog converter designed to handle high speed analog data output. Subroutine interfaces are provided for controlling the device in three different modes: multiple output, point plot output, single output.

Multiple Output
This interface controls the transfer of one or more buffers of data to either or both channels using DMA transfer. The channel number is specified by bit 15 (most significant bit) of each output value. If clear, the output is directed to channel 1; if set the output is directed to channel 2. The user is responsible for setting bit 15 of each value before the conversion operations begins. An external oscillator controls the timing of the conversions; with each pulse from the oscillator, one value is output. Once set up, the conversion process is controlled by the hardware, freeing the user to do other tasks.

ddaset initializes the DMA D/A for multiple output. buf1 points to a buffer of values to output. buf2 points to a second data buffer for double buffering(described below). If not double buffering, this value should be NULL. nsamp specifies the number of values in each of the output buffers.

When converting a single buffer, the user, after calling ddaset, prepares the buffer of data (including setting bit 15 to select the output channel) and begins the conversion process by calling ddaxbeg. To determine when the entire buffer has been processed, the user may test ddaone which returns non-zero when the process is finished. Alternatinvely, the user may catch the software signal SIFDDA by calling signal(2F) after ddaset but before ddaxbeg. The arguments passed to the signal catching routine are the signal number, the device file descriptor, and the address of the buffer just output.

In double buffering, after calling ddaset, the user program prepares the first buffer, indicates to the DMA D/A that the buffer is ready by incrementing the synchroniztion variable ddafull, and calls ddaxbeg. While the first buffer is being output, the user prepares the second buffer and again increments ddafull. When the DMA D/A finishes outputing the first buffer, it decrements ddafull to indicate to the user program that buffer is free and starts processing the second buffer. Thereafter, the user program waits for the next buffer to finish outputting by testing for ddafull less than DDAFULL, prepares that buffer, and increments ddafull. To determine when a buffer is finished, the user may also catch the signal SIGDDDA by calling signal(2F) after ddaset and before ddaxbeg. Operation continues until the user stops preparing buffers and incrementing ddafull. When ddafull reaches 0, conversions stop. Alternatively, the user program may call ddaxend to halt processing immediately.

If the two output buffers can be prepared in advance and never change, then there is no need to synchronize double buffering operations. Before calling ddaxbeg, ddafull is set to DDACONT (for continuous) and the DMA D/A alternatly outputs the two buffers until ddaxend is called.

Point Plot Output
This interface differs from the multiple output interface in that it outputs the data as pairs of values sending the first to channel 1 and the second to channel 2. In this case npnts specifies the number of pairs to output.

Single Output
ddawrite outputs a single value ( dval ) to one channel ( chan ). It is not necessary to indicate the channel number by modifying the sign bit.


/* Multiple output, single buffer */
#include <stdio_p.h>
#include <dmada_u.h>
#define NSAMP 1000
unsigned dbuf[NSAMP];

register int i;

   ... 	/* prepare buffer */

  ...	/* mark for channel 1 */

for(i = 0;i < NSAMP;dbuf[i++]&=077777);
	errexit(1,"ddaset err\n");
while (ddadone == 0)

/* Multiple Output, double buffer */
#include <stdio_p.h>
#include <dmada_u.h>

#defube NSAMP 1000
#define NBUF 100

unsigned dbuf1[NSAMP], dbuf2[NSAMP];

main ()
register int i;
register unsigned *nextbufm *tmp;

if(ddaset(NSAMP, dbuf1, dbuf2, NULL)== -1)
	errexit(1,"ddaset err\n");

	/* mark for channel 2 */
for(i = 0;i < NSAMP;dbuf1[i++]|=0100000);


	if(nextbuf == dbuf1)
		nextbuf = dbuf2;
		nextbuf = dbuf1;
	while (ddafull == DDAFULL)
	... /* prepare next buffer */
	for(i = 1;tmp = nextbuf; i < NSAMP; *tmp++|=0100000);


Ddaset, ddapnt, and ddawrite each return -1 if they are passed illegal arguments.


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