📄 pci550x_dac0_dma.c
字号:
/* * pci550x user program - DAC0 DMA Acquisition * * This test program uses a clock signal from either the internal DAC0 * PACER clock or the external clock source, DACLKIN, to clock the DAC. * Output data is written directly to the DAC0 FIFO via DMA, and then * clocked to generate the voltage ouput at the DAC0 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 DAC0 FIFO is written continuously. If * the output rate exceeds the rate at which the DAC0 FIFO can be kept * non-empty by DMA operations, the DAC0 FIFO will underflow and DAC * conversions are automatically disabled by the hardware. * * Invoke this test program from the command line as follows: * * $ ./pci550x_dac0_dma -f /dev/pci550xN [-p] [-u] [-d USECS | -F NSECS] * [-s SAMPLES] [-g | -G | -t | -T] [-x | -X ] [-b] * * -f /dev/pci550xN = device node (N=device #) * -p = packed data mode * -u = unipolar * -d USECS = delay between DAC conversions in microseconds * -F NSECS = .25 usec delay between DAC conversions * -s SAMPLES = number sample outputs per DMA buffer * -g = DAC external gate DATGIN (active low) * -G = DAC external gate DATGIN (active high) * -t = DAC external trigger DATGIN (falling edge) * -T = DAC external trigger DATGIN (rising edge) * -x = external clock DACLKIN (falling edge) * -X = external clock DACLKIN (rising edge) * -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_dac0_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 dac0_status;int dac0_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 long ndelay = 64;unsigned short samples = PCI550X_DAC_FIFO;int gate_enabled = PCI550X_FALSE;int g = PCI550X_DISABLE; int G = PCI550X_DISABLE;int t = PCI550X_DISABLE; int T = PCI550X_DISABLE;int X = PCI550X_DISABLE; int x = PCI550X_DISABLE;int F = PCI550X_DISABLE; int S = PCI550X_DISABLE;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 DAC0 DMA */ rc = ioctl(fd, PCI550X_IOCT_DA0_DMAEN, PCI550X_DISABLE); if(rc == -1) { perror("ioctl PCI550X_IOCT_DA0_DMAEN"); free(buf); exit(1); } else { printf("DAC0 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:F:gGtTxXb")) != -1) switch(c) { case 'd': if ((sscanf(optarg, "%ld", &udelay)) == 0) udelay = 10000; break; case 'F': if ((sscanf(optarg, "%ld", &ndelay)) == 0) ndelay = 64; F = PCI550X_ENABLE; 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_dac0_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("-F NSECS = .25 microseconds delay between " "DAC conversions\n"); printf("-s SAMPLES = number of output samples per DMA " "buffer\n"); printf("-g, DAC external gate DATGIN (active low)\n"); printf("-G, DAC external gate DATGIN (active high)\n"); printf("-t, DAC external trigger (falling edge)\n"); printf("-T, DAC external trigger (rising edge)\n"); printf("-x, external clock DACLKIN (falling edge)\n"); printf("-X, external clock DACLKIN (rising edge)\n"); printf("-b, brief output listing\n"); exit(0); case 'g': g = PCI550X_ENABLE; break; case 'G': G = PCI550X_ENABLE; break; case 't': t = PCI550X_ENABLE; break; case 'T': T = PCI550X_ENABLE; break; case 'X': X = PCI550X_ENABLE; break; case 'x': x = PCI550X_ENABLE; break; 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 DAC0 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 DAC0 */ rc = ioctl(fd, PCI550X_IOCT_DAC_SELECT, PCI550X_DAC0); if(rc == -1) { perror("ioctl PCI550X_IOC_DAC_SELECT"); free(buf); exit(1); } else { printf("DAC0 Subsystem selected\n"); } /* select DAC0 PACER Clock Source */ if (x) { rc = ioctl(fd, PCI550X_IOCT_DA0_CLOCK_SOURCE, DAC0_EXF_CLK); if(rc == -1) { perror("ioctl PCI550X_IOCT_DA0_CLOCK_SOURCE"); exit(1); } else { printf("External Clock Source (falling edge)\n"); } } else if (X) { rc = ioctl(fd, PCI550X_IOCT_DA0_CLOCK_SOURCE, DAC0_EXR_CLK); if(rc == -1) { perror("ioctl PCI550X_IOCT_DA0_CLOCK_SOURCE"); exit(1); } else { printf("External Clock Source (rising edge)\n"); } } else { rc = ioctl(fd, PCI550X_IOCT_DA0_CLOCK_SOURCE, DAC0_IP_CLK); if(rc == -1) { perror("ioctl PCI550X_IOCT_DA0_CLOCK_SOURCE"); exit(1); } else { printf("Internal Pacer Clock Source enabled\n"); } /* set the PACER CLOCK RATE */ if (F) { rc = ioctl(fd, PCI550X_IOCT_DA0_FPCEN, PCI550X_ENABLE); if(rc == -1) { perror("ioctl PCI550X_IOCT_DA0_FPCEN"); exit(1); } rc = ioctl(fd, PCI550X_IOCS_DAC0_FAST_CLOCK_RATE, &ndelay); if(rc == -1) { perror("ioctl " "PCI550X_IOCS_DAC0_FAST_CLOCK_RATE"); exit(1); } else { printf("DAC0 Pacer clock(0.25 usecs): %lu\n", ndelay); } } else { rc = ioctl(fd, PCI550X_IOCT_DA0_FPCEN, PCI550X_DISABLE); if(rc == -1) { perror("ioctl PCI550X_IOCT_DA0_FPCEN"); exit(1); } rc = ioctl(fd, PCI550X_IOCS_DAC0_PACER_CLOCK_RATE, &udelay); if(rc == -1) { perror("ioctl " "PCI550X_IOCS_DAC0_PACER_CLOCK_RATE"); exit(1); } else { printf("DAC0 Pacer clock(nsecs): %ld\n", udelay); } } } /* enable DAC0 FIFO */ rc = ioctl(fd, PCI550X_IOCT_DA0_STATUS_FFEN, PCI550X_ENABLE); if(rc == -1) { perror("ioctl PCI550X_IOCT_DA0_STATUS_FFEN"); free(buf); exit(1); } else { printf("DAC0 FIFO enabled\n"); } /* Set DMA Buffer Size */ rc = ioctl(fd, PCI550X_IOCT_DAC0_DMA_BYTES, buf_size); if(rc == -1) { perror("ioctl PCI550X_IOCT_DAC0_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_DA0_PDM, packed); if(rc == -1) { perror("ioctl PCI550X_IOCT_DA0_PDM"); free(buf); exit(1); } else { if (packed) printf("PDM enabled\n"); else printf("PDM disabled\n"); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -