⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pci550x_dac1_dma.c

📁 linux下面
💻 C
字号:
/* * pci550x user program - DAC1 DMA Acquisition * * This test program uses a clock signal from either the internal DAC1 * PACER clock or the external clock source, DACLKIN, to clock the DAC. * Output data is written directly to the DAC1 FIFO via DMA, and then * clocked to generate the voltage ouput at the DAC1 port. This mode of * operation is referred to as DMA, meaning that interrupts and DMA * functions are used to output the sample data.  In this method of * operating the DAC, the non-full DAC1 FIFO is written continuously.  If * the output rate exceeds the rate at which the DAC1 FIFO can be kept * non-empty by DMA operations,  the DAC1 FIFO will underflow and DAC * conversions are automatically disabled by the hardware. * * Invoke this test program from the command line as follows: * * $ ./pci550x_dac1_dma -f /dev/pci550xN [-p] [-u] [-d USECS] [-s SAMPLES] [-b] * *      -f /dev/pci550xN        = device node (N=device #) *      -p                      = packed data mode *      -u                      = unipolar *      -d USECS                = delay between DAC conversions in microseconds *	-s SAMPLES		= number sample outputs per DMA buffer *	-b			= brief output listing  * * EXAMPLE: run the test on device 3 in packed unipolar data mode at * 10ms DAC conversion rate with 100 samples outputs per DMA buffer * * $ ./pci550x_dac1_dma -f /dev/pci550x3 -p -u -d10000 -s100 * */#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/fcntl.h>#include <sys/ioctl.h>#include <signal.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <linux/limits.h>#define _PCI550X_USE_DAC_RANGE_TABLES#include "pci550x.h"/* GLOBLA DATA */int i,c;int dac1_status;int dac1_ctrl;unsigned int *buf = NULL;size_t buf_size;ssize_t bytes;char device[PATH_MAX] = "/dev/pci550x0";int packed = PCI550X_DISABLE;int bipolar = PCI550X_ENABLE;unsigned long udelay = PCI550X_NOMINAL_DAC_RATE;unsigned short samples = PCI550X_DAC_FIFO;int gate_enabled = PCI550X_FALSE;int brief = PCI550X_DISABLE;char sentinal[6] = {'-','\\','-','|','-','/'}; unsigned char mm = 0;union {unsigned int dac_data;short bp_dac_data[2];unsigned short up_dac_data[2];} dma;int fd, rc;int brd_type;void sighandler(int signum) {         /* Disable DAC1 DMA */        rc = ioctl(fd, PCI550X_IOCT_DA1_DMAEN, PCI550X_DISABLE);        if(rc == -1) {                perror("ioctl PCI550X_IOCT_DA1_DMAEN");		free(buf);                exit(1);        } else {		printf("DAC1 DMA halted\n");        }	/* free the output buffer */	free(buf);	/* close the device */	close(fd);	exit(0);}int main(int argc, char **argv) {         /* get command line args */        opterr = 0;        while ((c = getopt(argc, argv, "f:uphd:s:b")) != -1)                 switch(c) {                 case 'd':                        if ((sscanf(optarg, "%ld", &udelay)) == 0)                                udelay = 10000;                        break;                case 'f':                        strncpy(device, optarg, PATH_MAX);                        break;                case 'u':                        bipolar = PCI550X_DISABLE;                        break;                case 's':                        if ((sscanf(optarg, "%hd", &samples)) == 0) {				printf("error: invalid sample count\n");				exit(1);			}			if (!samples) {				printf("error: sample count is zero\n");				exit(1);			}                        break;                case 'p':                        packed = PCI550X_ENABLE;                        break;                case 'h':                        printf("usage: pci550x_dac1_dma -f /dev/pci550xN "                                "[-p] [-u] [-d USECS] [-s SAMPLES]\n");                        printf("-f /dev/pci550xN where N = board number\n");                        printf("-p, packed data mode\n");                        printf("-u, unipolar mode\n");                        printf("-d USECS = microseconds delay between "                                "DAC conversions\n");			printf("-s SAMPLES = number of output samples per DMA "				"buffer\n");			printf("-b, brief output listing\n");                        exit(0);		case 'b':			brief = PCI550X_ENABLE;			break;                default:                        break;                }        /* allocate an output buffer */	buf_size = samples << 2; /* DMA requires 4 bytes (32 bit) per sample */        buf = (unsigned int *)malloc(buf_size);        if (!buf) {		perror("failed to allocate DAC1 DMA output buffer");                exit(1);        }	/* open the device */	fd = open(device, O_WRONLY);	if(fd == -1) {		perror("open failed");		free(buf);		exit(1);	} else {		printf("open succeeded on %s\n", device);	}	/* query device type */	rc = ioctl(fd, PCI550X_IOCG_BRD_TYPE, &brd_type);	if(rc == -1) {		perror("ioctl PCI550X_IOCG_BRD_TYPE");		free(buf);		exit(1);	} else {		printf("ADAC Board Type:  %s\n", brd_names[brd_type]);	}        /* select DAC1 */        rc = ioctl(fd, PCI550X_IOCT_DAC_SELECT, PCI550X_DAC1);        if(rc == -1) {                perror("ioctl PCI550X_IOC_DAC_SELECT");		free(buf);                exit(1);        } else {                printf("DAC1 Subsystem selected\n");        }	/* select internal Pacer Clock source */	rc = ioctl(fd, PCI550X_IOCT_DA1_CLOCK_SOURCE, DAC1_IP_CLK);	if(rc == -1) {		perror("ioctl PCI550X_IOCT_DA1_CLOCK_SOURCE");		exit(1);	} else {		printf("Internal Pacer Clock Source enabled\n");	}	/* select DAC1 Pacer clock rate */	rc = ioctl(fd, PCI550X_IOCS_DAC1_PACER_CLOCK_RATE,		&udelay);	if(rc == -1) {		perror("ioctl "			"PCI550X_IOCS_DAC1_PACER_CLOCK_RATE");		exit(1);	} else {		printf("DAC1 Pacer clock(nsecs): %ld\n",			udelay);	}	/* enable DAC1 FIFO */	rc = ioctl(fd, PCI550X_IOCT_DA1_STATUS_FFEN, PCI550X_ENABLE);	if(rc == -1) {		perror("ioctl PCI550X_IOCT_DA1_STATUS_FFEN");		free(buf);		exit(1);	} else {		printf("DAC1 FIFO enabled\n");	}	/* Set DMA Buffer Size */	rc = ioctl(fd, PCI550X_IOCT_DAC1_DMA_BYTES, buf_size);        if(rc == -1) {                perror("ioctl PCI550X_IOCT_DMA_BYTES");		free(buf);                exit(1);        } else {		printf("DMA Buffer Size: %d bytes\n", buf_size);        }	/* disable/enable packed data mode */	rc = ioctl(fd, PCI550X_IOCT_DA1_PDM, packed);	if(rc == -1) {		perror("ioctl PCI550X_IOCT_DA1_PDM");		free(buf);		exit(1);	} else {		if (packed)			printf("PDM enabled\n");		else			printf("PDM disabled\n");	}	/* select bipolar/unipolar mode */	rc = ioctl(fd, PCI550X_IOCT_DA1_UB, bipolar);	if(rc == -1) {		perror("ioctl PCI550X_IOCT_DA1_UB");		free(buf);		exit(1);	} else {		if (bipolar) {			printf("Bipolar mode enabled\n");		} else {			printf("Unipolar mode enabled\n");		}	}	/* DAC1 output buffer initial values */	if (packed && bipolar) {		dma.bp_dac_data[0] = drt.bp_min;		dma.bp_dac_data[1] = drt.bp_min + 1;	} else if (packed && (!(bipolar))) {		dma.up_dac_data[0] = drt.up_min;		dma.up_dac_data[1] = drt.up_min + 1;	} else if (bipolar) {		dma.bp_dac_data[0] = drt.bp_min;		dma.bp_dac_data[1] = 0;	} else {		dma.up_dac_data[0] = drt.up_min;		dma.up_dac_data[1] = 0;	}         /* DAC1 DMA Enable */        rc = ioctl(fd, PCI550X_IOCT_DA1_DMAEN, PCI550X_ENABLE);        if(rc == -1) {                perror("ioctl PCI550X_IOCT_DA1_DMAEN");		free(buf);                exit(1);        } else {                printf("DMA enabled\n");        }	/* install the signal handler */	signal(SIGINT, &sighandler);	while(1) {		/* fill output buffer */		for (i = 0; i < samples; i++) {			buf[i] = dma.dac_data;			if (packed && bipolar)				if (dma.bp_dac_data[1] >= (drt.bp_max)) {					dma.bp_dac_data[0] = drt.bp_min;					dma.bp_dac_data[1] = drt.bp_min + 1;				} else {					dma.bp_dac_data[0] += 2;					dma.bp_dac_data[1] += 2;				}			else if (packed && (!bipolar))				if (dma.up_dac_data[1] >= (drt.up_max)) {					dma.up_dac_data[0] = drt.up_min;					dma.up_dac_data[1] = drt.up_min + 1;				} else {					dma.up_dac_data[0] += 2;					dma.up_dac_data[1] += 2;				}			else if (bipolar) {				if (dma.bp_dac_data[0] >= (drt.bp_max)) {					dma.bp_dac_data[0] = drt.bp_min;				} else {					dma.bp_dac_data[0]++;				}			} else 				if (dma.up_dac_data[1] >= (drt.up_max)) {					dma.up_dac_data[0] = drt.up_min;				} else {					dma.up_dac_data[0]++;				}		}		/* blocking write to DAC1 */		bytes = 0;		while (bytes < buf_size) {			bytes += 				write(fd, (void *)buf + bytes,					 buf_size - bytes);			if(bytes == -1) {				perror("pci550x write");				rc = ioctl(fd, PCI550X_IOCQ_DAC1_STATUS);				if (rc == -1) {					perror("ioctl "					 "PCI550X_IOCQ_DAC1_STATUS");					free(buf);					exit(1);				} else {					printf("DAC1 status 0x%x:", rc);					if (rc & DA1_STATUS_MERR1)						printf("merr1\n");					else if (rc & DA1_STATUS_MERR0)						printf("merr0\n");					else if (rc & DA1_STATUS_FOVR)						printf("fifo overflow\n");					else if (rc & DA1_STATUS_DERR)						printf("fifo underflow\n");					else if (rc & DA1_STATUS_CERR)						printf("clocking error\n");					else						printf("DMA process error\n");					free(buf);					exit(1);				}				free(buf);				exit(1);			}		}		/* brief display */		if (brief) {		if (packed && bipolar)			printf("%c:%s:%s DAC0 writes %d bytes, "				"(P,B) %d sample values\n",				sentinal[mm++], device,				brd_names[brd_type], buf_size,				buf_size >> 1);		else if (packed & (!bipolar) )			printf("%c:%s:%s DAC0 writes %d bytes, "				"(P,U) %d sample values\n",				sentinal[mm++], device,				brd_names[brd_type], buf_size,				buf_size >> 1);		else if (bipolar)			printf("%c:%s:%s DAC0 writes %d bytes, "				"(U,B) %d sample values\n",				sentinal[mm++], device,				brd_names[brd_type], buf_size,				buf_size >> 2);		else			printf("%c:%s:%s DAC0 writes %d bytes, "				"(U,U) %d sample values\n",				sentinal[mm++], device,				brd_names[brd_type], buf_size,				buf_size >> 2);		mm %= sizeof(sentinal);		} else {		/* display output buffer contents */		for (i = 0 ; i < samples; i++ ) {			dma.dac_data = buf[i];			if (packed && bipolar)				printf("%s:%s DAC1 DMA data "				"(P,B):"				"0x%04hx; %f Volts\n"				"%s:%s DAC1 DMA data "				"(P,B):"				"0x%04hx; %f Volts\n",				device, brd_names[brd_type],				dma.bp_dac_data[0],				dma.bp_dac_data[0] *					drt.bp_res,				device, brd_names[brd_type],				dma.bp_dac_data[1],				dma.bp_dac_data[1] *					drt.bp_res);			else if (packed && (!bipolar))				printf("%s:%s DAC1 DMA data "				"(P,U):"				"0x%04hx; %f Volts\n"				"%s:%s DAC1 DMA data "				"(P,U):"				"0x%04hx; %f Volts\n",				device, brd_names[brd_type],				dma.up_dac_data[0],				dma.up_dac_data[0] *					drt.up_res,				device, brd_names[brd_type],				dma.up_dac_data[1],				dma.up_dac_data[1] *					drt.up_res);			else if (bipolar)				printf("%s:%s DAC1 DMA data "				"(U,B):"				"0x%04hx; "				" %f Volts\n",				device, brd_names[brd_type],				dma.bp_dac_data[0],				dma.bp_dac_data[0] *					drt.bp_res);			else				printf("%s:%s DAC1 DMA data "				" (U,U):"				"0x%04hx; "				"%f Volts\n",				device, brd_names[brd_type],				dma.up_dac_data[0],				dma.up_dac_data[0] *					drt.up_res);		}		} 		/* start clocking the DAC on FIFO not empty  */		rc = ioctl(fd, PCI550X_IOCG_DA1_STATUS, &dac1_status);        	if(rc == -1) {			perror("ioctl PCI550X_IOCG_DA1_STATUS");			free(buf);			exit(1);		}		if ( (dac1_status & DA1_STATUS_FNE) && (!gate_enabled) ) {		/* enable DAC1 to do conversions */		rc = ioctl(fd, PCI550X_IOCT_DA1_CVEN, PCI550X_ENABLE);		if(rc == -1) {			perror("ioctl PCI550X_IOCT_DA1_CVEN");			free(buf);			exit(1);		} else {			printf("DAC1 enabled to do conversions\n");		}		gate_enabled = PCI550X_TRUE;		}	} /* end while */	free(buf);	close(fd);	return(0);	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -