double get_adc_volts(int chan, int diff, int range) { lsampl_t data[OVER_SAMPLE]; // adc burst data buffer int retval; comedi_range *ad_range; comedi_insn daq_insn; ADC_ERROR = FALSE; // global fault flag if (diff == TRUE) { aref_ai = AREF_DIFF; } else { aref_ai = AREF_GROUND; } // configure the AI channel for reads daq_insn.subdev = subdev_ai; daq_insn.chanspec = CR_PACK(chan, range, aref_ai); daq_insn.insn = INSN_READ; daq_insn.n = OVER_SAMPLE; daq_insn.data = data; retval = comedi_do_insn(it, &daq_insn); // send one instruction to the driver if (retval < 0) { comedi_perror("comedi_do_insn in get_adc_volts"); ADC_ERROR = TRUE; bmc.raw[chan] = 0; return 0.0; } ad_range = comedi_get_range(it, subdev_ai, chan, range); bmc.raw[chan] = data[0]; return comedi_to_phys(data[0], ad_range, maxdata_ai); // return the double result }
int comedi_data_read(comedi_t * dev, unsigned int subdev, unsigned int chan, unsigned int range, unsigned int aref, lsampl_t * data) { comedi_insn insn; memset(&insn, 0, sizeof(insn)); insn.insn = INSN_READ; insn.n = 1; insn.data = data; insn.subdev = subdev; insn.chanspec = CR_PACK(chan, range, aref); return comedi_do_insn(dev, &insn); }
int comedi_dio_config(struct comedi_device *dev, unsigned int subdev, unsigned int chan, unsigned int io) { struct comedi_insn insn; memset(&insn, 0, sizeof(insn)); insn.insn = INSN_CONFIG; insn.n = 1; insn.data = &io; insn.subdev = subdev; insn.chanspec = CR_PACK(chan, 0, 0); return comedi_do_insn(dev, &insn); }
int comedi_data_write(void *dev, unsigned int subdev, unsigned int chan, unsigned int range, unsigned int aref, unsigned int data) { struct comedi_insn insn; memset(&insn, 0, sizeof(insn)); insn.insn = INSN_WRITE; insn.n = 1; insn.data = &data; insn.subdev = subdev; insn.chanspec = CR_PACK(chan, range, aref); return comedi_do_insn(dev, &insn); }
int comedi_data_read_hint(void *dev, unsigned int subdev, unsigned int chan, unsigned int range, unsigned int aref) { struct comedi_insn insn; unsigned int dummy_data; memset(&insn, 0, sizeof(insn)); insn.insn = INSN_READ; insn.n = 0; insn.data = &dummy_data; insn.subdev = subdev; insn.chanspec = CR_PACK(chan, range, aref); return comedi_do_insn(dev, &insn); }
double get_adc_volts(int chan, int diff, int range) { lsampl_t data[OVER_SAMPLE]; // adc burst data buffer int retval, intg, i; comedi_range *ad_range; comedi_insn daq_insn; ADC_ERROR = FALSE; // global fault flag if (diff == TRUE) { aref_ai = AREF_DIFF; } else { aref_ai = AREF_GROUND; } intg = 0; // clear the integration counter // configure the AI channel for burst reads of OVER_SAMPLE times with the passed params daq_insn.subdev = subdev_ai; daq_insn.chanspec = CR_PACK(chan, range, aref_ai); daq_insn.insn = INSN_READ; daq_insn.n = OVER_SAMPLE; daq_insn.data = data; retval = comedi_do_insn(it, &daq_insn); // send one instruction to the driver if (retval < 0) { comedi_perror("comedi_do_insn in get_adc_volts"); ADC_ERROR = TRUE; bmc.raw[chan] = 0; return 0.0; } for (i = 0; i < OVER_SAMPLE; i++) { intg += data[i]; } data[0] = intg >> OVER_SAMPLE_SHIFTS; ad_range = comedi_get_range(it, subdev_ai, chan, range); bmc.raw[chan] = data[0]; return comedi_to_phys(data[0], ad_range, ((1 << (OVER_SAMPLE_ADC + OVER_SAMPLE_BITS)) - 1)); // return the double result }
int comedi_dio_bitfield(struct comedi_device *dev, unsigned int subdev, unsigned int mask, unsigned int *bits) { struct comedi_insn insn; unsigned int data[2]; int ret; memset(&insn, 0, sizeof(insn)); insn.insn = INSN_BITS; insn.n = 2; insn.data = data; insn.subdev = subdev; data[0] = mask; data[1] = *bits; ret = comedi_do_insn(dev, &insn); *bits = data[1]; return ret; }
int main(int argc, char *argv[]) { int ret; comedi_insn insn; lsampl_t d[5]; comedi_t *device; int freq; struct parsed_options options; init_parsed_options(&options); options.freq = -1; // we hijack this option to switch it on or off options.n_scan = -1; options.value = -1; parse_options(&options, argc, argv); if ((options.value==-1)&&(options.n_scan==-1)&&(options.freq==-1)) { fprintf(stderr, "Usage: %s OPTIONS duty_cycle\n" "options: \n" " -N 0 switches PWM off\n" " -N 1 switches PWM on\n" " -N 2 enquires the max value for the duty cycle\n" " -F FREQ sets the PWM frequency\n", argv[0]); } device = comedi_open(options.filename); if(!device){ comedi_perror(options.filename); exit(-1); } options.subdevice = comedi_find_subdevice_by_type(device,COMEDI_SUBD_PWM,0); if (options.verbose) printf("PWM subdevice autodetection gave subdevice number %d\n", options.subdevice); if(options.n_scan==2) { printf("%d\n",comedi_get_maxdata(device,options.subdevice,0)); comedi_close(device); exit(0); } insn.insn=INSN_CONFIG; insn.data=d; insn.subdev=options.subdevice; insn.chanspec=CR_PACK(0,0,0); if(options.n_scan==1) { d[0] = INSN_CONFIG_ARM; d[1] = 0; insn.n=2; ret=comedi_do_insn(device,&insn); if(ret < 0){ fprintf(stderr,"Could not switch on:%d\n",ret); comedi_perror(options.filename); exit(-1); } } if(options.n_scan==0) { d[0] = INSN_CONFIG_DISARM; d[1] = 0; insn.n=1; ret=comedi_do_insn(device,&insn); if(ret < 0){ fprintf(stderr,"Could not switch off:%d\n",ret); comedi_perror(options.filename); exit(-1); } } if(options.freq>0) { freq = options.freq; d[0] = INSN_CONFIG_PWM_SET_PERIOD; d[1] = 1E9/freq; insn.n=2; ret=comedi_do_insn(device,&insn); if(ret < 0){ fprintf(stderr,"Could set frequ:%d\n",ret); comedi_perror(options.filename); exit(-1); } } d[0] = INSN_CONFIG_GET_PWM_STATUS; insn.n=2; ret=comedi_do_insn(device,&insn); if(ret < 0){ fprintf(stderr,"Could not get status:%d insn=%d\n", ret, d[0]); comedi_perror(options.filename); exit(-1); } if (options.verbose) { if (d[1]) fprintf(stderr, "PWM is on.\n"); else fprintf(stderr, "PWM is off.\n"); } d[0] = INSN_CONFIG_PWM_GET_PERIOD; insn.n=2; ret=comedi_do_insn(device,&insn); if(ret < 0){ fprintf(stderr,"Could get frequ:%d\n",ret); comedi_perror(options.filename); exit(-1); } freq = 1E9 / d[1]; if (options.verbose) fprintf(stderr,"PWM frequency is %d\n", freq); if (options.value>=0) if(comedi_data_write(device, options.subdevice, options.channel, 0, 0, options.value)<0) { fprintf(stderr,"error setting the pwm duty cycle on "); comedi_perror(options.filename); exit(1); } return 0; }
int main(void) { RTIME until; RT_TASK *task; comedi_insn insn[NCHAN]; unsigned int read_chan[NICHAN] = { 0 }; unsigned int write_chan[NOCHAN] = { 0 }; #if !SINGLE_INSN comedi_insnlist ilist = { NCHAN, insn }; #endif #if SIN_FREQ lsampl_t sinewave; double omega = (2.0*M_PI*SIN_FREQ)/1.0E9; double actualtime; #endif lsampl_t *hist; lsampl_t data[NCHAN]; long i, k, n, retval; int toggle; FILE *fp; double tms[2]; #if SINGLE_INSN printf("single insn true\n"); #endif #if SIN_FREQ printf(" true\n"); #endif signal(SIGKILL, endme); signal(SIGTERM, endme); hist = malloc(SAMP_FREQ*RUN_TIME*NCHAN*sizeof(lsampl_t) + 1000); memset(hist, 0, SAMP_FREQ*RUN_TIME*NCHAN*sizeof(lsampl_t) + 1000); start_rt_timer(0); task = rt_task_init_schmod(nam2num("MYTASK"), 1, 0, 0, SCHED_FIFO, 0xF); printf("COMEDI INSN%s TEST BEGINS: SAMPLING FREQ: %d, RUN TIME: %d.\n", SINGLE_INSN ? "" : "LIST", SAMP_FREQ, RUN_TIME); mlockall(MCL_CURRENT | MCL_FUTURE); rt_make_hard_real_time(); if (init_board()) {; printf("Board initialization failed.\n"); return 1; } for (i = 0; i < NICHAN; i++) { BUILD_AREAD_INSN(insn[i], subdevai, data[i], 1, read_chan[i], AI_RANGE, AREF_GROUND); } for (i = 0; i < NOCHAN; i++) { BUILD_AWRITE_INSN(insn[NICHAN + i], subdevao, data[NICHAN + i], 1, write_chan[i], AO_RANGE, AREF_GROUND); } printf("done building.\n"); fflush (stdout); until = rt_get_time(); for (toggle = n = k = 0; k < SAMP_FREQ*RUN_TIME && !end; k++) { #if SIN_FREQ actualtime = count2nano(rt_get_time()); if(k<2) tms[k] = actualtime; sinewave = (int) (maxdatao/8*sin(omega*actualtime)); data[NICHAN] = sinewave+maxdatao/2; //data[NICHAN + 1] = -sinewave+maxdatao/2; #else data[NICHAN] = toggle*maxdatao/2; data[NICHAN + 1] = (1 - toggle)*maxdatao/2; toggle = 1 - toggle; #endif #if SINGLE_INSN for (i = 0; i < NCHAN; i++) { if ((retval = comedi_do_insn(dev, insn + i)) > 0) { hist[n++] = data[i]; } else { printf("Comedi insn failed # %ld out of %d instructions, retval %ld.\n", i, NCHAN, retval); break; } } #else if ((retval = rt_comedi_do_insnlist(dev, &ilist)) == NCHAN) { for (i = 0; i < NCHAN; i++) { hist[n++] = data[i]; } } else { printf("Comedi insnlist processed only %lu out of %d instructions.\n", retval, NCHAN); break; } #endif rt_sleep_until(until += nano2count(SAMP_TIME)); } comedi_cancel(dev, subdevai); comedi_cancel(dev, subdevao); comedi_data_write(dev, subdevao, 0, 0, AREF_GROUND, 2048); comedi_data_write(dev, subdevao, 1, 0, AREF_GROUND, 2048); comedi_close(dev); printf("COMEDI INSN%s ENDS.\n", SINGLE_INSN ? "" : "LIST"); printf("t1: %g\n", tms[0]); printf("t2: %g\n", tms[1]); printf("tdiff: %g\n", tms[1]-tms[0]); fp = fopen("rec.dat", "w"); for (n = k = 0; k < SAMP_FREQ*RUN_TIME; k++) { fprintf(fp, "# %ld: ", k); for (i = 0; i < NCHAN; i++) { fprintf(fp, "%d\t", hist[n++]); } fprintf(fp, "\n"); } fclose(fp); free(hist); stop_rt_timer(); rt_make_soft_real_time(); rt_task_delete(task); return 0; }
static int configBoard( int board ) { MY_BOARD_HARDWARE *pBoardHard = myBoard_getHardwareBoard( board ); MY_BOARD_SOFTWARE *pBoardSoft = myBoard_getSoftwareBoard( board ); if (pBoardHard == NULL || pBoardSoft == NULL) return -1; comedi_insn insn; lsampl_t p_insn_data[3]; int i; int status; insn.insn = INSN_CONFIG; insn.data = p_insn_data; insn.subdev = pBoardHard->subDeviceNumber; insn.n = 2; insn.data[0] = INSN_CONFIG_BLOCK_SIZE; insn.data[1] = 256; for(i=0; i < pBoardSoft->numberOfActiveAnalogInputs; i++){ int indexRange = pBoardHard->channelIndexRange[i]; insn.chanspec=CR_PACK( i, indexRange, pBoardHard->analogReference ); status = comedi_do_insn( pBoardHard->p_comediFileHandle, &insn ); if (status<0) { fprintf( stderr, "failed do inst for board[%d]\n", board ); return -1; } } if (pBoardHard->maxDataIsChannelSpecific || pBoardHard->rangeIsChannelSpecific) { for(i=0; i < pBoardSoft->numberOfActiveAnalogInputs; i++){ const comedi_range *pVoltageRange = comedi_get_range( pBoardHard->p_comediFileHandle, pBoardHard->subDeviceNumber, i, pBoardHard->channelIndexRange[i] ); int rawMax = comedi_get_maxdata( pBoardHard->p_comediFileHandle, pBoardHard->subDeviceNumber, i ); pBoardHard->channelRawToVoltA[i] = (pVoltageRange->max - pVoltageRange->min) / rawMax; pBoardHard->channelRawToVoltB[i] = pVoltageRange->min; fprintf( stderr, "set convert CONST for board[%d] channel[%d] a=%lf b=%lf\n", board, i, pBoardHard->channelRawToVoltA[i], pBoardHard->channelRawToVoltB[i] ); }/* for channel */ } else { const comedi_range *pVoltageRange = comedi_get_range( pBoardHard->p_comediFileHandle, pBoardHard->subDeviceNumber, 0, pBoardHard->channelIndexRange[0] ); int rawMax = comedi_get_maxdata( pBoardHard->p_comediFileHandle, pBoardHard->subDeviceNumber, 0 ); double rawToVoltA = (pVoltageRange->max - pVoltageRange->min) / rawMax; double rawToVoltB = pVoltageRange->min; fprintf( stderr, "set convert CONST for all channel on board[%d] a=%lf b=%lf\n", board, rawToVoltA, rawToVoltB ); for(i=0; i < pBoardSoft->numberOfActiveAnalogInputs; i++){ pBoardHard->channelRawToVoltA[i] = rawToVoltA; pBoardHard->channelRawToVoltB[i] = rawToVoltB; } } return 0; }