static int reference_set_bits(unsigned int bits) { unsigned int data[2] = { A4L_INSN_CONFIG_ALT_SOURCE, bits}; a4l_insn_t insn; int err; insn.data_size = sizeof(data); insn.type = A4L_INSN_CONFIG; insn.idx_subd = ai_subd.idx; insn.chan_desc = 0; insn.data = data; err = a4l_snd_insn(&descriptor, &insn); if (err) error(EXIT, 0, "a4l_snd_insn (%d)", err); return 0; }
static int data_write(long int *data, struct a4l_calibration_subdev *s, int channel, int range, int aref) { a4l_insn_t insn; int err; memset(&insn, 0, sizeof(insn)); insn.chan_desc = PACK(channel, range, aref); insn.idx_subd = s->idx; insn.type = A4L_INSN_WRITE; insn.data = data; insn.data_size = sizeof(*data); err = a4l_snd_insn(&descriptor, &insn); if (err < 0) error(EXIT, 0, "a4l_snd_insn (%d)", err); return 0; }
/* * subdevice operations */ static int data_read_hint(struct a4l_calibration_subdev *s, int channel, int range, int aref) { sampl_t dummy_data; a4l_insn_t insn; int err; memset(&insn, 0, sizeof(insn)); insn.chan_desc = PACK(channel, range, aref); insn.idx_subd = s->idx; insn.type = A4L_INSN_READ; insn.data = &dummy_data; insn.data_size = 0; err = a4l_snd_insn(&descriptor, &insn); if (err < 0) error(EXIT, 0, "a4l_snd_insn (%d)", err); return 0; }
[0] = A4L_INSN_CONFIG_PWM_OUTPUT, [1] = TRIG_ROUND_NEAREST, [2] = h, [3] = TRIG_ROUND_NEAREST, [4] = d }; a4l_insn_t insn; int err; insn.data_size = sizeof(data); insn.idx_subd = s->idx; insn.type = A4L_INSN_CONFIG; insn.chan_desc = 0; insn.data = data; err = a4l_snd_insn(&descriptor, &insn); if (err) error(EXIT, 0, "a4l_snd_insn (%d)", err); *rh = data[2]; *rd = data[4]; return 0; } static int reference_read_doubles(double dst[], unsigned int nb_samples, int speriod, int irange) { int i, err = 0; sampl_t *p;
/*!***************************************************************************** ******************************************************************************* \note initNI6259 \date Nov. 2009 \remarks Initializes the communication with the DAQ ******************************************************************************* Function Parameters: [in]=input,[out]=output \param[in] ad_only_flag: only initialize A/D convert \return TRUE for sucess, or FALSE if there was a problem ******************************************************************************/ int init_NI6259(int ad_only_flag) { int i,rc; static int ni6259_initialized = FALSE; unsigned int data[10]; a4l_insn_t insn; int real_osc_enabled = FALSE; if (ni6259_initialized) return TRUE; // Open the device rc = a4l_open(&desc, DEVICE); if (rc < 0) { printf("initNI6259: a4l_open %s failed (rc=%d)\n",DEVICE, rc); return FALSE; } // Fill the descriptor completely, as a4l_open only does a partial job. // First, allocate a buffer so as to get more info (subd, chan, rng) desc.sbdata = malloc(desc.sbsize); if (desc.sbdata == NULL) { printf("initNI6259: malloc failed \n"); return FALSE; } // Second, get the data rc = a4l_fill_desc(&desc); if (rc < 0) { printf("initNI6259: a4l_fill_desc %s failed (rc=%d)\n",DEVICE, rc); return FALSE; } // activate the analog outputs for the oscilloscope debugging if (read_parameter_pool_int(config_files[PARAMETERPOOL],"real_osc_enabled", &rc)) real_osc_enabled = rc; if (real_osc_enabled) setD2AFunction(d2a_NI6259); if (!ad_only_flag) { // plot some output about device //printDeviceInfo(&desc); // enable the counter clock // makeCounterClock(1000, FALSE); // route DIO16 (PFI) to PFI channels for (i=0; i<16; ++i) { insn.type = A4L_INSN_CONFIG; insn.idx_subd = SUBDEV_PFI; insn.chan_desc = i; insn.data_size = sizeof(data[0])*2; data[0] = A4L_INSN_CONFIG_SET_ROUTING; data[1] = NI_PFI_OUTPUT_PFI_DO; insn.data = data; rc = a4l_snd_insn(&desc, &insn); if (rc < 0) fprintf(stderr,"re-route PFI channels: routing of channe %d failed (rc=%d)\n",i,rc); } // set DIO32 channels to READ mode by default dio32_NI6259_config(0xffffffff, DIO_READ); // set DIO16 channels to READ mode by default dio16_NI6259_config(0xffffffff, DIO_READ); } // all done ni6259_initialized = TRUE; return TRUE; }
/*!***************************************************************************** ******************************************************************************* \note dio32_NI6259_write_cmd_buffer \date Jan. 2011 \remarks Uses the cmd structure to write a command buffer to the DIO device at very high communication rate. This function with the abort statement at the end is still experimental and is not really used so far. ******************************************************************************* Function Parameters: [in]=input,[out]=output \param[in] buf : the command buffer \param[in] n_buf: number of elements to write ******************************************************************************/ int dio32_NI6259_write_cmd_buffer(int *buf, int n_buf) { int i,j,rc; static unsigned long buf_size; unsigned long buf_left; static int *map = NULL; static int firsttime = TRUE; unsigned int chans[32]={ 0,1,2,3,4,5,6,7, 8,9,10,11,12,13,14,15, 16,17,18,19,20,21,22,23, 24,25,26,27,28,29,30,31}; a4l_cmd_t cmd = { .idx_subd = SUBDEV_DIO, .flags = 0, .start_src = TRIG_INT, // internal trigger .start_arg = 0, .scan_begin_src = TRIG_EXT, .scan_begin_arg = NI_CDIO_SCAN_BEGIN_SRC_G0_OUT, // channel used to trigger the scans .convert_src = TRIG_NOW, .convert_arg = 0, /* in ns */ .scan_end_src = TRIG_COUNT, .scan_end_arg = 32, .stop_src = TRIG_NONE, .stop_arg = 0, .nb_chan = 32, .chan_descs = chans, }; a4l_insn_t insn = { .type = A4L_INSN_INTTRIG, .idx_subd = SUBDEV_DIO, .data_size = 0, }; if (firsttime) { firsttime = FALSE; // map the communication buffer to user space // Get the buffer size to map rc = a4l_get_bufsize(&desc, SUBDEV_DIO, &buf_size); if (rc < 0) { printf("a4l_get_bufsize() failed (rc=%d)\n",rc); return FALSE; } // Map the subdevice buffer rc = a4l_mmap(&desc, SUBDEV_DIO, buf_size, (void *)&map); if (rc < 0) { printf("a4l_mmap() failed (rc=%d)\n",rc); return FALSE; } } // configure device in write mode rc = dio32_NI6259_config(ajcDATAMASK | ajcCTRLMASK,DIO_WRITE); if (rc < 0) { printf("write_cmd_buffer: dio32_NI6259_config failed (ret=%d)\n", rc); return FALSE; } // send the command rc = a4l_snd_command(&desc, &cmd); if (rc < 0) { printf("write_cmd_buffer: a4l_snd_command failed (ret=%d)\n", rc); return FALSE; } // write buf to the map buffer for (i=1; i<=n_buf; ++i) map[i-1] = buf[i]; // tell the device the size of the data rc = a4l_mark_bufrw(&desc, SUBDEV_DIO, n_buf*sizeof(int), &buf_left); if (rc < 0) { printf("a4l_mark_bufrw() failed (rc=%d)\n",rc); return FALSE; } // trigger the communication rc = a4l_snd_insn(&desc, &insn); if (rc < 0) printf("ni_test: triggering failed (rc=%d)\n",rc); // check whether the device is busy and wait int count_busy = 0; const int max_count_busy = 1000; while ((rc = a4l_poll(&desc, SUBDEV_DIO, A4L_INFINITE)) > 0) { // wait for completion if (++count_busy > max_count_busy) { printf("write_cmd_buffer: dio32_NI6259_config too many (%d) EBUSY timeouts\n", max_count_busy); return FALSE; } taskDelay(10000); } if (rc < 0 && rc!= -EPIPE) { printf("a4l_poll() failed (rc=%d)\n",rc); return FALSE; } return TRUE; } /*!***************************************************************************** ******************************************************************************* \note dio16_NI6259_read \date Feb 2010 \remarks reads from PFI device a 16 bit value with bit mask ******************************************************************************* Function Parameters: [in]=input,[out]=output \param[in] mask : which bits to read \param[out] val : the value read ******************************************************************************/ inline int dio16_NI6259_read(int mask, int *val) { int i; int rc; // configure the device to read mode for (i=0; i<16; ++i) { if ( ((1 << i) & mask) > 0) { if (dio16_channel_mode[i] != DIO_READ) { rc = a4l_config_subd(&desc,SUBDEV_PFI,A4L_INSN_CONFIG_DIO_INPUT,i); if (rc < 0) { printf("dio16_NI6259_read: failed to configure DIO (rc=%d, channel %d)\n",rc,i); return FALSE; } dio16_channel_mode[i] = DIO_READ; } } } // read the value rc = a4l_sync_dio(&desc, SUBDEV_PFI, &mask, val); if (rc < 0) { printf("dio16_NI6259_read: failed to communicate to DIO (rc=%d)\n",rc); return FALSE; } *val = (*val) & mask; return TRUE; } /*!***************************************************************************** ******************************************************************************* \note dio16_NI6259_write \date Feb 2010 \remarks writes to DIO device a 16 bit value with bit mask ******************************************************************************* Function Parameters: [in]=input,[out]=output \param[in] mask : which bits to write \param[in] val : the value to write ******************************************************************************/ inline int dio16_NI6259_write(int mask, int val) { int i; int rc; // configure the device channels to read mode if needed for (i=0; i<16; ++i) { if ( ((1 << i) & mask) > 0) { if (dio16_channel_mode[i] != DIO_WRITE) { rc = a4l_config_subd(&desc,SUBDEV_PFI,A4L_INSN_CONFIG_DIO_OUTPUT,i); if (rc < 0) { printf("dio16_NI6259_write: failed to configure DIO (rc=%d, channel %d)\n",rc,i); return FALSE; } dio16_channel_mode[i] = DIO_WRITE; } } } // write the value rc = a4l_sync_dio(&desc, SUBDEV_PFI, &mask, &val); if (rc < 0) { printf("dio16_NI6259_write: failed to communicate to DIO (rc=%d)\n",rc); return FALSE; } return TRUE; }
static int makeCounterClock(unsigned int period_ns, int debug_on_pfi_1) { int i,j,rc; lsampl_t counter_mode; const unsigned clock_period_ns = 50; /* 20MHz base clock */ unsigned int up_ticks, down_ticks; unsigned int data[10]; unsigned int up_time_ns = period_ns/2; a4l_insn_t insn; // disarm clock just in case it is still running insn.type = A4L_INSN_CONFIG; insn.idx_subd = SUBDEV_COUNTER; insn.chan_desc = 0; insn.data_size = sizeof(data[0])*2; data[0] = A4L_INSN_CONFIG_DISARM; data[1] = NI_GPCT_ARM_IMMEDIATE; insn.data = data; rc = a4l_snd_insn(&desc, &insn); if (rc < 0) fprintf(stderr,"makeCounterClock: arm counter failed (rc=%d)\n",rc); // route counter to output channel if (debug_on_pfi_1) { // first, configure the PFI0 channel as output channel rc = a4l_config_subd(&desc,SUBDEV_PFI,A4L_INSN_CONFIG_DIO_OUTPUT,0); if (rc < 0) fprintf(stderr,"makeCounterClock: PFI output failed (rc=%d)\n",rc); // second configure the PFI1 channel as input channel, so we can route // PFI0 to PFI1 with a wire, if we wish rc = a4l_config_subd(&desc,SUBDEV_PFI,A4L_INSN_CONFIG_DIO_INPUT,CHANNEL_PFI); if (rc < 0) fprintf(stderr,"makeCounterClock: PFI input failed (rc=%d)\n",rc); // and now route the signal insn.type = A4L_INSN_CONFIG; insn.idx_subd = SUBDEV_PFI; insn.chan_desc = 0; insn.data_size = sizeof(data[0])*2; data[0] = A4L_INSN_CONFIG_SET_ROUTING; data[1] = NI_PFI_OUTPUT_GOUT0; insn.data = data; rc = a4l_snd_insn(&desc, &insn); if (rc < 0) fprintf(stderr,"makeCounterClock: routing of counter failed (rc=%d)\n",rc); } // reset counter insn.type = A4L_INSN_CONFIG; insn.idx_subd = SUBDEV_COUNTER; insn.chan_desc = 0; insn.data_size = sizeof(data[0]); data[0] = A4L_INSN_CONFIG_RESET; insn.data = data; rc = a4l_snd_insn(&desc, &insn); if (rc < 0) fprintf(stderr,"makeCounterClock: reset counter failed (rc=%d)\n",rc); // set the gate source insn.type = A4L_INSN_CONFIG; insn.idx_subd = SUBDEV_COUNTER; insn.chan_desc = 0; insn.data_size = sizeof(data[0])*3; data[0] = A4L_INSN_CONFIG_SET_GATE_SRC; data[1] = 0; data[2] = NI_GPCT_DISABLED_GATE_SELECT | CR_EDGE; insn.data = data; rc = a4l_snd_insn(&desc, &insn); if (rc < 0) fprintf(stderr,"makeCounterClock: set gate source failed (rc=%d)\n",rc); data[1] = 1; rc = a4l_snd_insn(&desc, &insn); if (rc < 0) fprintf(stderr,"makeCounterClock: set gate source failed (rc=%d)\n",rc); // set counter mode counter_mode = NI_GPCT_COUNTING_MODE_NORMAL_BITS; // toggle output on terminal count counter_mode |= NI_GPCT_OUTPUT_TC_TOGGLE_BITS; // load on terminal count counter_mode |= NI_GPCT_LOADING_ON_TC_BIT; // alternate the reload source between the load a and load b registers counter_mode |= NI_GPCT_RELOAD_SOURCE_SWITCHING_BITS; // count down counter_mode |= NI_GPCT_COUNTING_DIRECTION_DOWN_BITS; // initialize load source as load b register counter_mode |= NI_GPCT_LOAD_B_SELECT_BIT; // don't stop on terminal count counter_mode |= NI_GPCT_STOP_ON_GATE_BITS; // don't disarm on terminal count or gate signal counter_mode |= NI_GPCT_NO_HARDWARE_DISARM_BITS; insn.type = A4L_INSN_CONFIG; insn.idx_subd = SUBDEV_COUNTER; insn.chan_desc = 0; insn.data_size = sizeof(data[0])*2; data[0] = A4L_INSN_CONFIG_SET_COUNTER_MODE; data[1] = counter_mode; insn.data = data; rc = a4l_snd_insn(&desc, &insn); if (rc < 0) fprintf(stderr,"makeCounterClock: set counter mode failed (rc=%d)\n",rc); // set clock source: 20 MHz clock insn.type = A4L_INSN_CONFIG; insn.idx_subd = SUBDEV_COUNTER; insn.chan_desc = 0; insn.data_size = sizeof(data[0])*3; data[0] = A4L_INSN_CONFIG_SET_CLOCK_SRC; data[1] = NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS; data[2] = clock_period_ns; insn.data = data; rc = a4l_snd_insn(&desc, &insn); if (rc < 0) fprintf(stderr,"makeCounterClock: set clock source failed (rc=%d)\n",rc); up_ticks = (up_time_ns + clock_period_ns / 2) / clock_period_ns; down_ticks = (period_ns + clock_period_ns / 2) / clock_period_ns - up_ticks; // set initial counter value by writing to channel 0 rc = a4l_sync_write(&desc,SUBDEV_COUNTER, 0, 0,&down_ticks, 4); if (rc < 0) fprintf(stderr,"makeCounterClock: writing down_ticks 0 failed (rc=%d)\n",rc); // set "load a" register to the number of clock ticks the counter output should remain low // by writing to channel 1. rc = a4l_sync_write(&desc,SUBDEV_COUNTER, 1, 0,&down_ticks, 4); if (rc < 0) fprintf(stderr,"makeCounterClock: writing down_ticks 1 failed (rc=%d)\n",rc); // set "load b" register to the number of clock ticks the counter output should remain high // by writing to channel 2 rc = a4l_sync_write(&desc,SUBDEV_COUNTER, 2, 0,&up_ticks, 4); if (rc < 0) fprintf(stderr,"makeCounterClock: writing up_ticks 2 failed (rc=%d)\n",rc); // arm the counter insn.type = A4L_INSN_CONFIG; insn.idx_subd = SUBDEV_COUNTER; insn.chan_desc = 0; insn.data_size = sizeof(data[0])*2; data[0] = A4L_INSN_CONFIG_ARM; data[1] = NI_GPCT_ARM_IMMEDIATE; insn.data = data; rc = a4l_snd_insn(&desc, &insn); if (rc < 0) fprintf(stderr,"makeCounterClock: arm counter failed (rc=%d)\n",rc); return TRUE; }