📄 pci550x_dac0_ssa.c
字号:
/* * pci550x user program - DAC0 Single Sample Acquisition - Software Clock * * * This test program uses a software command to clock DAC0 by writing * to the DAC0_STATUS register. The sample data is written directly to * the DAC0 FIFO register where it is moved to the DAC0 port and converted * to a voltage output. This mode of operation is referred to as * "programmed I/O", meaning that no interrupts or DMA functions are * used to output the sample data. This is the simplest method of * operating the DAC, in many cases the least efficient, and the least * prone to error. * * Invoke this test program from the command line as follows: * * $ ./pci550x_dac0_ssa -f /dev/pci550xN [-p] [-u] [-d USECS] * [-g | -G | -t | -T] * * -f /dev/pci550xN = device node (N=device #) * -p = packed data mode * -u = unipolar * -d USECS = delay between DAC conversions in microseconds * -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) * * EXAMPLE: run the test on device 3 in packed unipolar data mode * converting every 100 microseconds * * $ ./pci550x_dac0_ssa -f /dev/pci550x3 -p -u -d100 */#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 <limits.h>#include <unistd.h> #include <getopt.h>#define __USE_GNU#include <string.h>#define _PCI550X_USE_DAC_RANGE_TABLES#include "pci550x.h"/* GLOBLA DATA */int i,c;int dac0_status;int packed = PCI550X_DISABLE;int bipolar = PCI550X_ENABLE;int g = PCI550X_DISABLE; int G = PCI550X_DISABLE;int t = PCI550X_DISABLE; int T = PCI550X_DISABLE;unsigned long delay = PCI550X_NOMINAL_DAC_RATE;int fd, rc;int brd_type;char device[PATH_MAX] = "/dev/pci550x0";union {unsigned int dac_fifo;short bp_dac_fifo[2];unsigned short up_dac_fifo[2];} u1;void sighandler(int signum) { /* user wants to quit */ if (signum) printf("received signal: %s, cleaning up...\n", strsignal(signum)); /* drain the DAC0 FIFO */ rc = ioctl(fd, PCI550X_IOCG_DA0_STATUS, &dac0_status); if(rc == -1) { perror("ioctl PCI550X_IOCG_DA0_STATUS"); exit(1); } while (dac0_status & DA0_STATUS_FNE) { /* wait for ready */ while (!(dac0_status & DA0_STATUS_READY)) { rc = ioctl(fd, PCI550X_IOCG_DA0_STATUS, &dac0_status); if(rc == -1) { perror("ioctl PCI550X_IOCG_DA0_STATUS"); exit(1); } } /* start conversion */ rc = ioctl(fd, PCI550X_IOC_DA0_STATUS_CONV, NULL); if(rc == -1) { perror("ioctl PCI550X_IOC_DA0_STATUS_CONV"); exit(1); } if (packed && bipolar) printf("%s:%s DAC0 data (P,B): 0x%04hx = " "%f Volts\n", device, brd_names[brd_type], u1.bp_dac_fifo[0], u1.bp_dac_fifo[0] * drt.bp_res); else if (packed && (!bipolar)) printf("%s:%s DAC0 data (P,U): 0x%04hx = " "%f Volts\n", device, brd_names[brd_type], u1.up_dac_fifo[0], u1.up_dac_fifo[0] * drt.up_res); else if (bipolar) printf("%s:%s DAC0 data (U,B): 0x%04hx = " "%f Volts\n", device, brd_names[brd_type], u1.bp_dac_fifo[0], u1.bp_dac_fifo[0] * drt.bp_res); else printf("%s:%s DAC0 data (U,U): 0x%04hx = " "%f Volts\n", device, brd_names[brd_type], u1.up_dac_fifo[0], u1.up_dac_fifo[0] * drt.up_res); rc = ioctl(fd, PCI550X_IOCG_DA0_STATUS, &dac0_status); if(rc == -1) { perror("ioctl PCI550X_IOCG_DA0_STATUS"); exit(1); } } printf("DAC0 FIFO Empty\n"); /* disable DAC0 to do conversions */ rc = ioctl(fd, PCI550X_IOCT_DA0_CVEN, PCI550X_DISABLE); if(rc == -1) { perror("ioctl PCI550X_IOCT_DA0_CVEN"); exit(1); } else { printf("DAC0 disabled to do conversions\n"); } /* disable DAC0 FIFO */ rc = ioctl(fd, PCI550X_IOCT_DA0_STATUS_FFEN, PCI550X_DISABLE); if(rc == -1) { perror("ioctl PCI550X_IOCT_DA0_STATUS_FFEN"); exit(1); } else { printf("DAC0 FIFO disabled\n"); } close(fd); exit(0);}int main(int argc, char **argv) { /* get command line args */ opterr = 0; while ((c = getopt(argc, argv, "f:uphd:gGtT")) != -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 'p': packed = PCI550X_ENABLE; break; case 'h': printf("usage: pci550x_dac0_ssa -f /dev/pci550xN " "[-p] [-u] [-d USECS] " "[-g | -G | -t | -T] \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 " "conversions\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"); 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; default: break; } /* open the device */ fd = open(device, O_RDWR); 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]); } /* install the signal handler */ signal(SIGINT, &sighandler); /* select Software Convert as DAC0 Pacer Clock Source */ rc = ioctl(fd, PCI550X_IOCT_DA0_CLOCK_SOURCE, DAC0_SW_CLK); if(rc == -1) { perror("ioctl PCI550X_IOCT_DA0_CLOCK_SOURCE"); exit(1); } else { printf("Software Convert enabled\n"); } /* disable/enable packed data mode */ rc = ioctl(fd, PCI550X_IOCT_DA0_PDM, packed); if(rc == -1) { perror("ioctl PCI550X_IOCT_DA0_PDM"); exit(1); } else { if (packed) printf("Packed Data Mode\n"); else printf("Unpacked Data Mode\n"); } /* enable DAC0 to do conversions */ rc = ioctl(fd, PCI550X_IOCT_DA0_CVEN, PCI550X_ENABLE); if(rc == -1) { perror("ioctl PCI550X_IOCT_DA0_CVEN"); exit(1); } else { printf("DAC0 enabled to do conversions\n"); } /* select gate source for the onboard pacer clock */ if (g | G | t | T) { rc = ioctl(fd, PCI550X_IOCT_DA0_CGSL, PCI550X_ENABLE); if(rc == -1) { perror("ioctl PCI550X_IOCT_DA0_CGSL"); exit(1); } else printf("DAC0 external "); if (g | G ) { rc = ioctl(fd, PCI550X_IOCT_DA0_TGSL, PCI550X_ENABLE); if(rc == -1) { perror("ioctl PCI550X_IOCT_DA0_TGSL"); exit(1); } else printf("level "); if (G) { rc = ioctl(fd, PCI550X_IOCT_DA0_TGPL, PCI550X_ENABLE); if(rc == -1) { perror("ioctl PCI550X_IOCT_DA0_TGPL"); exit(1); } else printf("(high) gate enabled\n"); g = PCI550X_DISABLE; } else { rc = ioctl(fd, PCI550X_IOCT_DA0_TGPL, PCI550X_DISABLE); if(rc == -1) { perror("ioctl PCI550X_IOCT_DA0_TGPL"); exit(1); } else printf("(low) gate enabled\n"); G = PCI550X_DISABLE; } t = T = PCI550X_DISABLE; } else { rc = ioctl(fd, PCI550X_IOCT_DA0_TGSL, PCI550X_DISABLE); if(rc == -1) { perror("ioctl PCI550X_IOCT_DA0_TGSL"); exit(1); } else printf("edge "); g = G = PCI550X_DISABLE; if (T) { rc = ioctl(fd, PCI550X_IOCT_DA0_TGPL, PCI550X_ENABLE); if(rc == -1) { perror("ioctl PCI550X_IOCT_DA0_TGPL"); exit(1); } else printf("(rising) trigger enabled\n"); t = PCI550X_DISABLE; } else { rc = ioctl(fd, PCI550X_IOCT_DA0_TGPL, PCI550X_DISABLE); if(rc == -1) { perror("ioctl PCI550X_IOCT_DA0_TGPL"); exit(1); } else printf("(falling) trigger enabled\n"); T = PCI550X_DISABLE; } } } else { rc = ioctl(fd, PCI550X_IOCT_DA0_CGSL, PCI550X_DISABLE); if(rc == -1) { perror("ioctl PCI550X_IOCT_DA0_CGSL"); exit(1); } else printf("DAC0 Internal Software Gate enabled\n"); } /* DAC gate enable */ if (g | G | t | T) { rc = ioctl(fd, PCI550X_IOCT_DA0_TGEN, PCI550X_ENABLE); if(rc == -1) { perror("ioctl PCI550X_IOCT_DA0_TGEN"); exit(1); } else { printf("DAC0 external gate enabled\n"); } } else { rc = ioctl(fd, PCI550X_IOCT_DA0_CGEN, PCI550X_ENABLE); if(rc == -1) { perror("ioctl PCI550X_IOCT_DA0_CGEN"); exit(1); } else { printf("DAC0 software gate enabled\n"); } } /* enable DAC0 FIFO */ rc = ioctl(fd, PCI550X_IOCT_DA0_STATUS_FFEN, PCI550X_ENABLE); if(rc == -1) { perror("ioctl PCI550X_IOCT_DA0_STATUS_FFEN"); exit(1); } else { printf("DAC0 FIFO enabled\n"); } /* select bipolar/unipolar mode */ rc = ioctl(fd, PCI550X_IOCT_DA0_UB, bipolar); if(rc == -1) { perror("ioctl PCI550X_IOCT_DA0_UB"); exit(1); } else { if (bipolar) { printf("Bipolar mode enabled\n"); } else { printf("Unipolar mode enabled\n"); } } /* set initial DAC value at minimum of the range */ if (packed && bipolar) { u1.bp_dac_fifo[0] = drt.bp_min; u1.bp_dac_fifo[1] = drt.bp_min + 1; } else if (packed && (!(bipolar))) { u1.up_dac_fifo[0] = drt.up_min; u1.up_dac_fifo[1] = drt.up_min + 1; } else if (bipolar) { u1.bp_dac_fifo[0] = drt.bp_min; u1.bp_dac_fifo[1] = 0; } else { u1.up_dac_fifo[0] = drt.up_min; u1.up_dac_fifo[1] = 0; } while(1) { /* write data to DAC0 FIFO */ rc = ioctl(fd, PCI550X_IOCS_DA0_FIFO, &u1.dac_fifo); if(rc == -1) { perror("ioctl PCI550X_IOCS_DA0_FIFO"); exit(1); } /* delay */ if (delay) usleep(delay); else { /* wait for ready */ do { rc = ioctl(fd, PCI550X_IOCG_DA0_STATUS, &dac0_status); if(rc == -1) { perror("ioctl PCI550X_IOCG_DA0_STATUS"); exit(1); } } while (!(dac0_status & DA0_STATUS_READY)); } while(1) { /* start conversion */ rc = ioctl(fd, PCI550X_IOC_DA0_STATUS_CONV, NULL); if(rc == -1) { if (errno == EAGAIN) printf("DAC gated OFF" " or waiting for trigger\n"); else { perror("ioctl PCI550X_IOC_DA0_STATUS_CONV"); exit(1); } } else break; } if (packed && bipolar) printf("%s:%s DAC0 data (P,B): 0x%04hx = " "%f Volts\n", device, brd_names[brd_type], u1.bp_dac_fifo[0], u1.bp_dac_fifo[0] * drt.bp_res); else if (packed && (!bipolar)) printf("%s:%s DAC0 data (P,U): 0x%04hx = " "%f Volts\n", device, brd_names[brd_type], u1.up_dac_fifo[0], u1.up_dac_fifo[0] * drt.up_res); else if (bipolar) printf("%s:%s DAC0 data (U,B): 0x%04hx = " "%f Volts\n", device, brd_names[brd_type], u1.bp_dac_fifo[0], u1.bp_dac_fifo[0] * drt.bp_res); else printf("%s:%s DAC0 data (U,U): 0x%04hx = " "%f Volts\n", device, brd_names[brd_type], u1.up_dac_fifo[0], u1.up_dac_fifo[0] * drt.up_res); if (packed) { /* delay */ if (delay) usleep(delay); else { /* wait for ready */ do { rc = ioctl(fd, PCI550X_IOCG_DA0_STATUS, &dac0_status); if(rc == -1) { perror("ioctl PCI550X_IOCG_DA0_STATUS"); exit(1); } } while (!(dac0_status & DA0_STATUS_READY)); } while(1) { /* start conversion */ rc = ioctl(fd, PCI550X_IOC_DA0_STATUS_CONV, NULL); if(rc == -1) { if (errno == EAGAIN) printf("DAC gated OFF" " or waiting for trigger\n"); else { perror("ioctl PCI550X_IOC_DA0_STATUS_CONV"); exit(1); } } else break; } if (packed && bipolar) printf("%s:%s DAC0 data (P,B): 0x%04hx = " "%f Volts\n", device, brd_names[brd_type], u1.bp_dac_fifo[1], u1.bp_dac_fifo[1] * drt.bp_res); else if (packed && (!bipolar)) printf("%s:%s DAC0 data (P,U): 0x%04hx = " "%f Volts\n", device, brd_names[brd_type], u1.up_dac_fifo[1], u1.up_dac_fifo[1] * drt.up_res); else if (bipolar) printf("%s:%s DAC0 data (U,B): 0x%04hx = " "%f Volts\n", device, brd_names[brd_type], u1.bp_dac_fifo[0], u1.bp_dac_fifo[0] * drt.bp_res); else printf("%s:%s DAC0 data (U,U): 0x%04hx = " "%f Volts\n", device, brd_names[brd_type], u1.up_dac_fifo[0], u1.up_dac_fifo[0] * drt.up_res); } /* ramp the output values */ if (packed && bipolar) if (u1.bp_dac_fifo[1] >= (drt.bp_max)) { u1.bp_dac_fifo[0] = drt.bp_min; u1.bp_dac_fifo[1] = drt.bp_min + 1; } else { u1.bp_dac_fifo[0] += 2; u1.bp_dac_fifo[1] += 2; } else if (packed && (!bipolar)) if (u1.up_dac_fifo[1] >= (drt.up_max)) { u1.up_dac_fifo[0] = drt.up_min; u1.up_dac_fifo[1] = drt.up_min + 1; } else { u1.up_dac_fifo[0] += 2; u1.up_dac_fifo[1] += 2; } else if (bipolar) if (u1.bp_dac_fifo[0] >= (drt.bp_max)) { u1.bp_dac_fifo[0] = drt.bp_min; } else { u1.bp_dac_fifo[0] ++; } else if (u1.up_dac_fifo[1] >= (drt.up_max)) { u1.up_dac_fifo[0] = drt.up_min; } else { u1.up_dac_fifo[0] += 1; } } /* end while */ close(fd); return(0); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -