📄 pci550x_adc_burst.c
字号:
/* * pci550x user program - ADC Clocked Acquisition * * Invoke this test program from the command line as follows: * * $ ./pci550x_adc_burst -f /dev/pci550xN [-p] [-u] [-c CHANNEL] [-d USECS] * [-b USECS] [-s SAMPLES] * * -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 * -b USECS = delay between bursts in microseconds * -s SAMPLES = number of samples per acquisition * * EXAMPLE: run the test on device 3 in packed, unipolar data mode at a 10ms * conversion rate, 100ms burst rate, starting at channel 1 with a 16 element * channel scan list * * $ ./pci550x_adc_burst -f /dev/pci550x3 -p -u -c1 -d10000 -b100000 -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 <string.h>#include <linux/limits.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,c;int ad_status;int ad_control;int adc_error;unsigned short channel = 0;unsigned short mux;unsigned short samples = ADC_CCRAM_MAX;unsigned short cindex;union { unsigned int ad_fifo; unsigned short fifo_up[2]; short fifo_bp[2];} u1;unsigned int gain = 0;int fd,rc;int brd_type;char device[PATH_MAX] = "/dev/pci550x0";char errmsg[80];int packed = PCI550X_DISABLE;int bipolar = PCI550X_ENABLE;unsigned long delay = 10000;unsigned long brate = 100000;void sighandler(int signum) { /* disable ADC pacer clock */ rc = ioctl(fd, PCI550X_IOCT_ADC_CGEN, PCI550X_DISABLE); if(rc == -1) { perror("ioctl PCI550X_IOCT_ADC_CGEN"); exit(1); } else { printf("ADC pacer clock disabled\n"); } /* flush the ADC pipeline */ rc = ioctl(fd, PCI550X_IOCT_ADC_CVEN, PCI550X_DISABLE); if(rc == -1) { perror("ioctl PCI550X_IOCT_ADC_CVEN"); exit(1); } else { printf("ADC disabled to do conversions\n"); } /* drain the ADC FIFO */ rc = ioctl(fd, PCI550X_IOCG_AD_STATUS, &ad_status); if(rc == -1) { perror("ioctl PCI550X_IOCG_AD_STATUS"); exit(1); } while (ad_status & AD_STATUS_FNE) { rc = ioctl(fd, PCI550X_IOCG_AD_FIFO, &u1.ad_fifo); if(rc == -1) { perror("ioctl PCI550X_IOCG_AD_FIFO"); exit(1); } else { if ((packed) && bipolar) printf("ADC Channel 0x%04hx " "raw data (PACKED,BIPOLAR):" "0x%04hx; %f Volts;\n" "ADC Channel 0x%04hx raw data (PACKED,BIPOLAR):" "0x%04hx; %f Volts\n", dl_ccram.ccram[cindex], u1.fifo_bp[1], u1.fifo_bp[1] * art[brd_type].bp_res[gain], dl_ccram.ccram[(cindex + 1) % samples], u1.fifo_bp[0], u1.fifo_bp[0] * art[brd_type].bp_res[gain]); else if (packed && (!bipolar)) printf("ADC Channel 0x%04hx " "raw data (PACKED,UNIPOLAR):" "0x%04hx; %f Volts;\n" "ADC Channel 0x%04hx " "raw data (PACKED,UNIPOLAR):" "0x%04hx; %f Volts\n", dl_ccram.ccram[cindex], u1.fifo_up[1], u1.fifo_up[1] * art[brd_type].up_res[gain], dl_ccram.ccram[(cindex + 1) % samples], u1.fifo_up[0], u1.fifo_up[0] * art[brd_type].up_res[gain]); else if (bipolar) printf("ADC Channel 0x%04hx " "raw data (UNPACKED,BIPOLAR):" "0x%04hx; %f Volts\n", u1.fifo_bp[1], u1.fifo_bp[0], u1.fifo_bp[0] * art[brd_type].bp_res[gain]); else printf("ADC Channel 0x%04hx " "raw data (UNPACKED,UNIPOLAR):" "0x%04hx; %f Volts\n", u1.fifo_up[1], u1.fifo_up[0], u1.fifo_up[0] * art[brd_type].up_res[gain]); if (packed) cindex += 2; else cindex++; cindex %= samples; } rc = ioctl(fd, PCI550X_IOCG_AD_STATUS, &ad_status); if(rc == -1) { perror("ioctl PCI550X_IOCG_AD_STATUS"); exit(1); } } printf("ADC FIFO empty\n"); close(fd); exit(0);}int main(int argc, char **argv) { /* get command line args */ opterr = 0; while ((c = getopt(argc, argv, "f:uc:phd:s:b:")) != -1) switch(c) { case 'd': if ((sscanf(optarg, "%ld", &delay)) == 0) delay = 10000; break; case 'b': if ((sscanf(optarg, "%ld", &brate)) == 0) brate = 100000; 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_burst -f /dev/pci550xN " "[-p] [-u] [-c CHANNEL] [-d USECS] " "[-s SAMPLES)\n"); printf("/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("-b USECS = microseconds delay between " "bursts\n"); printf("-s SAMPLES = number of samples in scan " "list\n"); exit(0); default: break; } /* open the device */ fd = open(device, O_RDONLY); if(fd == -1) { perror("open failed"); 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"); 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"); 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"); 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]); } /* set the PACER CLOCK RATE */ rc = ioctl(fd, PCI550X_IOCS_ADC_PACER_CLOCK_RATE, (int *)&brate); if(rc == -1) { perror("ioctl PCI550X_IOCS_ADC_PACER_CLOCK_RATE"); exit(1); } else { printf("Pacer clock(usecs): %lu\n", brate); } /* set the Burst Rate */ rc = ioctl(fd, PCI550X_IOCS_ADC_BURST_RATE, (int *)&delay); if(rc == -1) { perror("ioctl PCI550X_IOCS_ADC_BURST_RATE"); exit(1); } else { printf("Burst rate (usecs): %ld\n", delay); } /* select Internal Pacer Clock Source */ rc = ioctl(fd, PCI550X_IOCT_ADC_CLOCK_SOURCE, ADC_IP_CLK); if(rc == -1) { perror("ioctl PCI550X_IOCT_ADC_CLOCK_SOURCE"); exit(1); } else { printf("Pacer Clock Source selected\n"); } /* enable/disable packed data mode */ rc = ioctl(fd, PCI550X_IOCT_ADC_PDM, packed); if(rc == -1) { perror("ioctl PCI550X_IOCT_ADC_PDM"); exit(1); } else { if (packed) printf("PDM enabled\n"); else printf("PDM disabled\n"); } /* Burst Mode Enable */ rc = ioctl(fd, PCI550X_IOCT_ADC_BMDE, PCI550X_ENABLE); if(rc == -1) { perror("ioctl PCI550X_IOCT_ADC_BMDE"); exit(1); } else { printf("BURST Mode enabled\n"); } /* set the Burst Length */ rc = ioctl(fd, PCI550X_IOCS_ADC_BURST_LENGTH, (int *)&samples); if(rc == -1) { perror("ioctl PCI550X_IOCS_BURST_LENGTH"); exit(1); } else { printf("Burst length set at: %d\n", samples); } /* enable ADC to do conversions */ rc = ioctl(fd, PCI550X_IOCT_ADC_CVEN, PCI550X_ENABLE); if(rc == -1) { perror("ioctl PCI550X_IOCT_ADC_CVEN"); exit(1); } else { printf("ADC enabled to do conversions\n"); } /* enable ADC FIFO */ rc = ioctl(fd, PCI550X_IOCT_AD_STATUS_FFEN, PCI550X_ENABLE); if(rc == -1) { perror("ioctl PCI550X_IOCT_AD_STATUS_FFEN"); exit(1); } else { printf("ADC FIFO enabled\n"); } /* load the AD_CCRAM_D */ rc = ioctl(fd, PCI550X_IOCS_AD_CCRAM_I, NULL); if(rc == -1) { perror("ioctl PCI550X_IOCS_AD_CCRAM_I"); exit(1); } else { printf("AD_CCRAM_D loaded\n"); } /* wait for ready */ ad_status = cindex = 0; while (!(ad_status & AD_STATUS_READY)) { rc = ioctl(fd, PCI550X_IOCG_AD_STATUS, &ad_status); if(rc == -1) { perror("ioctl PCI550X_IOCG_AD_STATUS"); exit(1); } } printf("ADC Status Register ready\n"); /* enable ADC pacer clock */ rc = ioctl(fd, PCI550X_IOCT_ADC_CGEN, PCI550X_ENABLE); if(rc == -1) { perror("ioctl PCI550X_IOCT_ADC_CGEN"); exit(1); } else { printf("ADC pacer clock enabled\n"); } /* install the signal handler */ signal(SIGINT, &sighandler); adc_error = 0; while(1) { /* do this until we are asked to stop, or an error */ /* wait for FIFO not empty, or an error */ ad_status = 0; while (!(ad_status & AD_STATUS_FNE)) { rc = ioctl(fd, PCI550X_IOCG_AD_STATUS, &ad_status); if(rc == -1) { perror("ioctl PCI550X_IOCG_AD_STATUS"); exit(1); } if (ad_status & (AD_STATUS_FOVR | AD_STATUS_FUNDR | AD_STATUS_CERR | AD_STATUS_BERR) ) { adc_error = 1; break; } } if (adc_error) break; /* exit the big loop, fatal error */ /* drain the ADC FIFO */ while (ad_status & AD_STATUS_FNE) { rc = ioctl(fd, PCI550X_IOCG_AD_FIFO, &u1.ad_fifo); if(rc == -1) { perror("ioctl PCI550X_IOCG_AD_FIFO"); exit(1); } else { if (packed && bipolar) printf("ADC Channel 0x%04hx " "raw data (PACKED,BIPOLAR):" "0x%04hx; %f Volts;\n" "ADC Channel 0x%04hx raw data (PACKED,BIPOLAR):" "0x%04hx; %f Volts\n", dl_ccram.ccram[cindex % samples], u1.fifo_bp[1], u1.fifo_bp[1] * art[brd_type].bp_res[gain], dl_ccram.ccram[(cindex+1) % samples], u1.fifo_bp[0], u1.fifo_bp[0] * art[brd_type].bp_res[gain]); else if (packed && (!bipolar)) printf("ADC Channel 0x%04hx " "raw data (PACKED,UNIPOLAR):" "0x%04hx; %f Volts;\n" "ADC Channel 0x%04hx raw data (PACKED,UNIPOLAR):" "0x%04hx; %f Volts\n", dl_ccram.ccram[cindex % samples], u1.fifo_up[1], u1.fifo_up[1] * art[brd_type].up_res[gain], dl_ccram.ccram[(cindex+1) % samples], u1.fifo_up[0], u1.fifo_up[0] * art[brd_type].up_res[gain]); else if (bipolar) printf("ADC Channel 0x%04hx " "raw data (UNPACKED,BIPOLAR):" "0x%04hx; %f Volts\n", u1.fifo_bp[1], u1.fifo_bp[0], u1.fifo_bp[0] * art[brd_type].bp_res[gain]); else printf("ADC Channel 0x%04hx " "raw data (UNPACKED,UNIPOLAR):" "0x%04hx; %f Volts\n", u1.fifo_up[1], u1.fifo_up[0], u1.fifo_up[0] * art[brd_type].up_res[gain]); if (packed) cindex += 2; else cindex++; cindex %= samples; rc = ioctl(fd, PCI550X_IOCG_AD_STATUS, &ad_status); if(rc == -1) { perror("ioctl PCI550X_IOCG_AD_STATUS"); exit(1); } } } } /* end while */ /* disable ADC pacer clock */ rc = ioctl(fd, PCI550X_IOCT_ADC_CGEN, PCI550X_DISABLE); if(rc == -1) { perror("ioctl PCI550X_IOCT_ADC_CGEN"); exit(1); } else { printf("ADC pacer clock disabled\n"); } /* * ADC had an error, display the ADC Status Register and Exit */ printf("ADC Error: status register contents: 0x%08x\n", ad_status); if (ad_status & AD_STATUS_FOVR) printf("ADC FIFO overflow\n"); if (ad_status & AD_STATUS_FUNDR) printf("ADC FIFO underflow\n"); if (ad_status & AD_STATUS_CERR) printf("ADC clocking error\n"); if (ad_status & AD_STATUS_BERR) printf("ADC burst error\n"); close(fd); exit(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -