📄 pci550x_adc_dma.c
字号:
/* * pci550x user program - ADC DMA Acquistion * * This test program uses a clock signal from either the internal ADC * PACER clock or the external clock source, ADCLKIN, to clock the ADC. * Output data is read directly from the ADC FIFO via DMA, and then * converted to the voltage value. This mode of operation is referred to * as DMA, meaning that interrupts and DMA functions are used to acquire * the sample data. In this method of operating the ADC, the non-empty * ADC FIFO is read continuously. If the input rate exceeds the rate at * which the ADC FIFO can be kept non-full by DMA operations, the ADC * FIFO will overflow and ADC conversions are automatically disabled by the * hardware. * * Invoke this test program from the command line as follows: * * $ ./pci550x_adc_dma -f /dev/pci550xN [-p] [-u] [-c CHANNEL] [-d USECS] * [-d USECS | -F NSECS] [-s SAMPLES] * [-g | -G | -t | -T] [-o] [-O] [-E] * [-A CCOUNT] [-x | -X] * * -f /dev/pci550xN = device node (N=device #) * -p = packed data mode * -u = unipolar * -c CHANNEL = 16 bit hex channel number * -d USECS = delay between ADC conversions in microseconds * -F NSECS = .25 usec delay between ADC conversions * -s SAMPLES = number of samples per acquisition * -g = ADC external gate ADTGIN (active low) * -G = ADC external gate ADTGIN (active high) * -t = ADC external trigger ADTGIN (falling edge) * -T = ADC external trigger ADTGIN (rising edge) * -o = ADC external trigger output - ADTROUT * -O = ADC external clock output - ADCLKOUT * -E = ADC expansion inputs * -A CCOUNT = number of POST TRIGGER ADC conversions * -x = external clock ADCLKIN (falling edge) * -X = external clock ADCLKIN (rising edge) * -b = brief output listing * * EXAMPLE: run the test on device 3 in packed data mode at 10ms * starting at channel 0 in unipolar mode with a 16 element channel scan list * * $ ./pci550x_adc_dma -f /dev/pci550x3 -p -u -c0 -d10000 -s16 */#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 <linux/limits.h>#include <getopt.h>#define __USE_GNU#include <string.h>#define _PCI550X_USE_ADC_RANGE_TABLES#include "pci550x.h"/* GLOBLA DATA *//* channel list */adc_ccram dl_ccram; /* downloaded channel list */adc_ccram ul_ccram; /* uploaded channel list */int i,j,c;int ad_status;int ad_control;unsigned int gain;int bipolar = PCI550X_ENABLE;int g = PCI550X_DISABLE; int G = PCI550X_DISABLE;int t = PCI550X_DISABLE; int T = PCI550X_DISABLE;int o = PCI550X_DISABLE; int O = PCI550X_DISABLE;int E = PCI550X_DISABLE; int F = PCI550X_DISABLE;int X = PCI550X_DISABLE; int x = PCI550X_DISABLE;int A = PCI550X_DISABLE;int brief = PCI550X_DISABLE;unsigned short channel = 0;unsigned int ccount = 0;unsigned short samples = ADC_CCRAM_MAX;unsigned short mux;unsigned long udelay = PCI550X_NOMINAL_ADC_RATE;unsigned long ndelay = 64;int fd;int brd_type;int rc;int packed = PCI550X_DISABLE;char device[PATH_MAX] = "/dev/pci550x0";unsigned int *buf;size_t buf_size;ssize_t bytes;char sentinal[6] = {'-','\\','-','|','-','/'}; unsigned char mm = 0;union { unsigned int raw_data; unsigned short data_up[2]; short data_bp[2];} dma;void sighandler(int signum) { /* user wants to quit */ if (signum) printf("received signal: %s, cleaning up...\n", strsignal(signum)); /* Disable ADC DMA */ rc = ioctl(fd, PCI550X_IOCT_ADC_DMAEN, PCI550X_DISABLE); if(rc == -1) { perror("ioctl PCI550X_IOCT_ADC_DMAEN"); free(buf); exit(1); } else { printf("ADC DMA halted\n"); } /* ADC gate disable */ if (g | G | t | T) { rc = ioctl(fd, PCI550X_IOCT_ADC_TGEN, PCI550X_DISABLE); if(rc == -1) { perror("ioctl PCI550X_IOCT_ADC_TGEN"); exit(1); } else { printf("ADC external gate disabled\n"); } } else { rc = ioctl(fd, PCI550X_IOCT_ADC_CGEN, PCI550X_DISABLE); if(rc == -1) { perror("ioctl PCI550X_IOCT_ADC_CGEN"); exit(1); } else { printf("ADC software gate disabled\n"); } } /* ADC Convert Disable */ rc = ioctl(fd, PCI550X_IOCT_ADC_CVEN, PCI550X_DISABLE); if(rc == -1) { perror("ioctl PCI550X_IOCT_ADC_CVEN"); free(buf); exit(1); } else { printf("ADC Conversions disable\n"); } /* free the output buffer */ free(buf); close(fd); exit(0);}int main(int argc, char **argv) { /* get command line args */ opterr = 0; while ((c = getopt(argc, argv, "f:uc:phd:F:s:gGtToOEA:xXb")) != -1) switch(c) { case 'd': if ((sscanf(optarg, "%ld", &udelay)) == 0) udelay = PCI550X_NOMINAL_ADC_RATE; break; case 'f': strncpy(device, optarg, PATH_MAX); break; case 'u': bipolar = PCI550X_DISABLE; break; case 'c': if ((sscanf(optarg, "%hx", &channel)) == 0) channel = 0; break; case 's': if ((sscanf(optarg, "%hd", &samples)) == 0) samples = ADC_CCRAM_MAX; else { if (!samples) samples = ADC_CCRAM_MAX; else samples %= ADC_CCRAM_MAX+1; } break; case 'p': packed = PCI550X_ENABLE; break; case 'h': printf("usage: pci550x_adc_clk -f /dev/pci550xN " "[-p] [-u] [-c CHANNEL] [-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("-c CHANNEL = 16-bit hex channel number\n"); printf("-d USECS = microseconds delay between " "ADC conversions\n"); printf("-F NSECS = delay between ADC conversions " "in 0.25 microsecond increments\n"); printf("-s SAMPLES = number of samples in scan " "list\n"); printf("-g, ADC external gate ADTGIN (active low)\n"); printf("-G, ADC external gate ADTGIN (active high\n"); printf("-t, ADC external trigger" " ADTGIN (falling edge)\n"); printf("-T, ADC external trigger" " ADTGIN (rising edge)\n"); printf("-o, ADC external trigger ADTROUT\n"); printf("-O, ADC external clock ADCLKOUT\n"); printf("-E, ADC expansion inputs enable\n"); printf("-A, CCOUNT = number of POST TRIGGER " "ADC conversions\n"); printf("-x, external clock ADCLKIN (falling edge)\n"); printf("-X, external clock ADCLKIN (rising edge)\n"); printf("-b, brief output listing\n"); exit(0); case 'b': brief = PCI550X_ENABLE; break; 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 'o': o = PCI550X_ENABLE; break; case 'O': O = PCI550X_ENABLE; break; case 'E': E = PCI550X_ENABLE; break; case 'A': if ((sscanf(optarg, "%d", &ccount)) == 0) { printf("error: invalid ccount: %d\n", ccount); exit(1); } A = PCI550X_ENABLE; break; case 'x': x = PCI550X_ENABLE; break; case 'X': X = PCI550X_ENABLE; break; default: break; } /* packed data mode requires and even sample count */ if (packed && (samples % 2)) { printf("error: invalid odd sample count: %d\n", samples); printf("sample count must be even in packed data mode.\n"); exit(1); } /* allocate DMA buffer */ buf_size = samples * 4; /* DMA requires 4 bytes (32 bit) per sample */ buf = (unsigned int *)malloc(buf_size); if (!buf) { perror("failed to allocate DMA buffer"); exit(1); } /* open the device */ fd = open(device, O_RDONLY); 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]); } /* download the channel list */ gain = ((channel & AD_CCRAM_D_GN) >> 8); mux = channel & AD_CCRAM_D_MUX; channel &= (~AD_CCRAM_D_MUX); if (bipolar) channel &= (~AD_CCRAM_D_UB); else channel |= (AD_CCRAM_D_UB); for (i = 0; i < samples; i++, mux++, mux %= 256 ) dl_ccram.ccram[i] = channel | mux; dl_ccram.elements = samples; rc = ioctl(fd, PCI550X_IOCS_AD_CCRAM_D, &dl_ccram); if(rc == -1) { perror("ioctl PCI550X_IOCS_AD_CCRAM_D"); free(buf); exit(1); } else { printf("ADC Channel List Downloaded\n"); } /* upload the channel list */ rc = ioctl(fd, PCI550X_IOCG_AD_CCRAM_D, &ul_ccram); if(rc == -1) { perror("ioctl PCI550X_IOCS_AD_CCRAM_D"); free(buf); exit(1); } else { printf("ADC Channel List Uploaded\n"); printf("Number of Elements: %d\n", ul_ccram.elements); for (i = 0; i < ul_ccram.elements; i++) printf("ADC Element:%d-0x%x\n",i, ul_ccram.ccram[i]); } /* select Pacer Clock Source */ if (x) { rc = ioctl(fd, PCI550X_IOCT_ADC_CLOCK_SOURCE, ADC_EXF_CLK); if(rc == -1) { perror("ioctl PCI550X_IOCT_ADC_CLOCK_SOURCE"); exit(1); } else { printf("External Clock source ADCLKIN" " (falling edge) selected\n"); } } else if (X) { rc = ioctl(fd, PCI550X_IOCT_ADC_CLOCK_SOURCE, ADC_EXR_CLK); if(rc == -1) { perror("ioctl PCI550X_IOCT_ADC_CLOCK_SOURCE"); exit(1); } else { printf("External Clock source ADCLKIN" " (rising edge) selected\n"); } } else { rc = ioctl(fd, PCI550X_IOCT_ADC_CLOCK_SOURCE, ADC_IP_CLK);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -