📄 pci550x_adc_ssa.c
字号:
/* * pci550x user program - ADC Single Sample Acquisition - Software Clock * * This test program uses a software command to clock the ADC by writing * to the AD_STATUS register. The sample data is then read directly from * the ADC FIFO register and converted to a voltage reading. This mode of * operation is referred to as "programmed I/O", meaning that no interrupts * or DMA functions are used to acquire the sample data. This is the * simplest method of operating the ADC, in many cases the least efficient, * and the least prone to error. * * Invoke this test program from the command line as follows: * * $ ./pci550x_adc_ssa -f /dev/pci550xN [-p] [-u] [-c CHANNEL] [-d USECS] * [-g | -G | -t | -T] [-o] [-O] [-E] * [-A CCOUNT] * * -f /dev/pci550xN = device node (N=device #) * -p = packed data mode * -u = unipolar * -c CHANNEL = 16 bit hex channel number * -d USECS = microseconds between ADC conversions * -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 enabled * -A CCOUNT = number of POST TRIGGER ADC conversions * * EXAMPLE: run the test on device 3 in unipolar packed data mode on * channel 4 converting every 100 microseconds with ADCLKOUT enabled. * * $ ./pci550x_adc_ssa -f /dev/pci550x3 -p -u -c 4 -d100 -O */#include <stdio.h>#include <errno.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/fcntl.h>#include <sys/ioctl.h>#include <signal.h>#include <unistd.h>#include <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,c;unsigned int gain;int ad_status;unsigned short channel = 0;unsigned int ccount = 0;int brd_type;char device[PATH_MAX] = "/dev/pci550x0";char errmsg[80];union { unsigned int ad_fifo; unsigned short fifo_up[2]; short fifo_bp[2];} u1;int fd, rc;int packed = PCI550X_DISABLE;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 A = PCI550X_DISABLE;unsigned long delay = PCI550X_NOMINAL_ADC_RATE;void sighandler(int signum) { /* user wants to quit */ printf("received signal: %s, cleaning up...\n", strsignal(signum)); /* 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"); } } /* 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 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("%s:%s ADC Channel 0x%04hx " "(P,B):" "0x%04hx; %f Volts;\n" "%s ADC Channel 0x%04hx (P,B):" "0x%04hx; %f Volts\n", device, brd_names[brd_type], channel, u1.fifo_bp[1], u1.fifo_bp[1] * art[brd_type].bp_res[gain], device, channel, u1.fifo_bp[0], u1.fifo_bp[0] * art[brd_type].bp_res[gain]); else if (packed && (!bipolar)) printf("%s:%s ADC Channel 0x%04hx " "(P,U):" "0x%04hx; %f Volts;\n" "%s ADC Channel 0x%04hx " "(P,U):" "0x%04hx; %f Volts\n", device, brd_names[brd_type], channel, u1.fifo_up[1], u1.fifo_up[1] * art[brd_type].up_res[gain], device, channel, u1.fifo_up[0], u1.fifo_up[0] * art[brd_type].up_res[gain]); else if (bipolar) printf("%s:%s ADC Channel 0x%04hx " "(U,B):" "0x%04hx; %f Volts\n", device, brd_names[brd_type], u1.fifo_bp[1], u1.fifo_bp[0], u1.fifo_bp[0] * art[brd_type].bp_res[gain]); else printf("%s:%s ADC Channel 0x%04hx " "(U,U):" "0x%04hx; %f Volts\n", device, brd_names[brd_type], u1.fifo_up[1], u1.fifo_up[0], u1.fifo_up[0] * art[brd_type].up_res[gain]); } 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:gGtToOEA:")) != -1) switch(c) { case 'd': if ((sscanf(optarg, "%ld", &delay)) == 0) delay = 0; 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 'p': packed = PCI550X_ENABLE; break; case 'h': printf("usage: pci550x_adc_ssa -f /dev/pci550xN " "[-p] [-u] [-c CHANNEL] [-d USECS] " "[-g | -G | -t | -T] [-o] [-O] [-E]" "[-A CCOUNT]"); 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 between " "ADC conversions\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 output ADTROUT\n"); printf("-O, ADC external clock output ADCLKOUT\n"); printf("-E, ADC expansion inputs enabled\n"); printf("-A, CCOUNT = number of POST TRIGGER " "ADC conversions\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 '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; default: break; } /* open the device */ fd = open(device, O_RDWR); if(fd == -1) { sprintf(errmsg, "open failed on device %s", device); perror(errmsg); 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]); } /* install the signal handler */ signal(SIGINT, &sighandler); /* download the channel list */ dl_ccram.elements = 1; if (bipolar) channel &= (~(AD_CCRAM_D_UB)); else channel |= AD_CCRAM_D_UB; gain = ((channel & AD_CCRAM_D_GN) >> 8); dl_ccram.ccram[0] = channel; 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]); } /* verify the channel list */ if (ul_ccram.elements != dl_ccram.elements) { printf("ADC Channel List Verification Error:\n"); printf("\tNumber of Downloaded CCRAM Elements:%d\n", dl_ccram.elements); printf("\tNumber of Uploaded CCRAM Elements:%d\n", ul_ccram.elements); exit(1); } else for (i = 0; i < dl_ccram.elements; i++) if (ul_ccram.ccram[i] != dl_ccram.ccram[i]) break; if (i < dl_ccram.elements) { printf("ADC Channel List Verification Error:\n"); printf("Downloaded element %d:0x%x\n",i,dl_ccram.ccram[i]); printf("Uploaded element %d:0x%x\n",i,ul_ccram.ccram[i]); exit(1); } else printf("ADC Channel List Verified\n"); /* select Software Convert as ADC Pacer Clock Source */ rc = ioctl(fd, PCI550X_IOCT_ADC_CLOCK_SOURCE, ADC_SW_CLK); if(rc == -1) { perror("ioctl PCI550X_IOCT_ADC_CLOCK_SOURCE"); exit(1); } else { printf("Software Convert enabled\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("Packed Data Mode\n"); else printf("Unpacked Data Mode\n"); } /* About Trigger Mode */ if (A) { rc = ioctl(fd, PCI550X_IOCS_ADC_CCOUNT, (int *)&ccount); if (rc == -1) { perror("ioctl PCI550X_IOCS_ADC_CCOUNT"); exit(1); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -