Exemplo n.º 1
0
static int usbduxsigma_ao_insn_write(struct comedi_device *dev,
				     struct comedi_subdevice *s,
				     struct comedi_insn *insn,
				     unsigned int *data)
{
	struct usbduxsigma_private *devpriv = dev->private;
	unsigned int chan = CR_CHAN(insn->chanspec);
	int ret;
	int i;

	down(&devpriv->sem);
	if (devpriv->ao_cmd_running) {
		up(&devpriv->sem);
		return -EBUSY;
	}

	for (i = 0; i < insn->n; i++) {
		devpriv->dux_commands[1] = 1;		/* num channels */
		devpriv->dux_commands[2] = data[i];	/* value */
		devpriv->dux_commands[3] = chan;	/* channel number */
		ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_DA_CMD);
		if (ret < 0) {
			up(&devpriv->sem);
			return ret;
		}
		s->readback[chan] = data[i];
	}
	up(&devpriv->sem);

	return insn->n;
}
Exemplo n.º 2
0
static int usbduxsigma_pwm_start(struct comedi_device *dev,
				 struct comedi_subdevice *s)
{
	struct usbduxsigma_private *devpriv = dev->private;
	int ret;

	if (devpriv->pwm_cmd_running)
		return 0;

	devpriv->dux_commands[1] = devpriv->pwm_delay;
	ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_PWM_ON_CMD);
	if (ret < 0)
		return ret;

	memset(devpriv->pwm_urb->transfer_buffer, 0, devpriv->pwm_buf_sz);

	devpriv->pwm_cmd_running = 1;
	ret = usbduxsigma_submit_pwm_urb(dev);
	if (ret < 0) {
		devpriv->pwm_cmd_running = 0;
		return ret;
	}

	return 0;
}
Exemplo n.º 3
0
static int usbduxsigma_ai_cmd(struct comedi_device *dev,
			      struct comedi_subdevice *s)
{
	struct usbduxsigma_private *devpriv = dev->private;
	struct comedi_cmd *cmd = &s->async->cmd;
	unsigned int len = cmd->chanlist_len;
	uint8_t muxsg0 = 0;
	uint8_t muxsg1 = 0;
	uint8_t sysred = 0;
	int ret;
	int i;

	down(&devpriv->sem);

	/* set current channel of the running acquisition to zero */
	s->async->cur_chan = 0;
	for (i = 0; i < len; i++) {
		unsigned int chan  = CR_CHAN(cmd->chanlist[i]);

		create_adc_command(chan, &muxsg0, &muxsg1);
	}

	devpriv->dux_commands[1] = len;  /* num channels per time step */
	devpriv->dux_commands[2] = 0x12; /* CONFIG0 */
	devpriv->dux_commands[3] = 0x03; /* CONFIG1: 23kHz sample, delay 0us */
	devpriv->dux_commands[4] = 0x00; /* CONFIG3: diff. channels off */
	devpriv->dux_commands[5] = muxsg0;
	devpriv->dux_commands[6] = muxsg1;
	devpriv->dux_commands[7] = sysred;

	ret = usbbuxsigma_send_cmd(dev, USBBUXSIGMA_AD_CMD);
	if (ret < 0) {
		up(&devpriv->sem);
		return ret;
	}

	devpriv->ai_counter = devpriv->ai_timer;

	if (cmd->start_src == TRIG_NOW) {
		/* enable this acquisition operation */
		devpriv->ai_cmd_running = 1;
		ret = usbduxsigma_submit_urbs(dev, devpriv->ai_urbs,
					      devpriv->n_ai_urbs, 1);
		if (ret < 0) {
			devpriv->ai_cmd_running = 0;
			up(&devpriv->sem);
			return ret;
		}
		s->async->inttrig = NULL;
	} else {	/* TRIG_INT */
		/* wait for an internal signal and submit the urbs later */
		s->async->inttrig = usbduxsigma_ai_inttrig;
	}

	up(&devpriv->sem);

	return 0;
}
Exemplo n.º 4
0
static int usbduxsigma_ai_insn_read(struct comedi_device *dev,
				    struct comedi_subdevice *s,
				    struct comedi_insn *insn,
				    unsigned int *data)
{
	struct usbduxsigma_private *devpriv = dev->private;
	unsigned int chan = CR_CHAN(insn->chanspec);
	uint8_t muxsg0 = 0;
	uint8_t muxsg1 = 0;
	uint8_t sysred = 0;
	int ret;
	int i;

	down(&devpriv->sem);
	if (devpriv->ai_cmd_running) {
		up(&devpriv->sem);
		return -EBUSY;
	}

	create_adc_command(chan, &muxsg0, &muxsg1);

	/* Mode 0 is used to get a single conversion on demand */
	devpriv->dux_commands[1] = 0x16; /* CONFIG0: chopper on */
	devpriv->dux_commands[2] = 0x80; /* CONFIG1: 2kHz sampling rate */
	devpriv->dux_commands[3] = 0x00; /* CONFIG3: diff. channels off */
	devpriv->dux_commands[4] = muxsg0;
	devpriv->dux_commands[5] = muxsg1;
	devpriv->dux_commands[6] = sysred;

	/* adc commands */
	ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD);
	if (ret < 0) {
		up(&devpriv->sem);
		return ret;
	}

	for (i = 0; i < insn->n; i++) {
		uint32_t val;

		ret = usbduxsigma_receive_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD);
		if (ret < 0) {
			up(&devpriv->sem);
			return ret;
		}

		/* 32 bits big endian from the A/D converter */
		val = be32_to_cpu(get_unaligned((__be32
						 *)(devpriv->insn_buf + 1)));
		val &= 0x00ffffff;	/* strip status byte */
		val ^= 0x00800000;	/* convert to unsigned */

		data[i] = val;
	}
	up(&devpriv->sem);

	return insn->n;
}
Exemplo n.º 5
0
static int usbduxsigma_pwm_cancel(struct comedi_device *dev,
				  struct comedi_subdevice *s)
{
	struct usbduxsigma_private *devpriv = dev->private;

	/* unlink only if it is really running */
	usbduxsigma_pwm_stop(dev, devpriv->pwm_cmd_running);

	return usbbuxsigma_send_cmd(dev, USBDUXSIGMA_PWM_OFF_CMD);
}
Exemplo n.º 6
0
static int usbduxsigma_getstatusinfo(struct comedi_device *dev, int chan)
{
	struct usbduxsigma_private *devpriv = dev->private;
	uint8_t sysred;
	uint32_t val;
	int ret;

	switch (chan) {
	default:
	case 0:
		sysred = 0;		/* ADC zero */
		break;
	case 1:
		sysred = 1;		/* ADC offset */
		break;
	case 2:
		sysred = 4;		/* VCC */
		break;
	case 3:
		sysred = 8;		/* temperature */
		break;
	case 4:
		sysred = 16;		/* gain */
		break;
	case 5:
		sysred =  32;		/* ref */
		break;
	}

	devpriv->dux_commands[1] = 0x12; /* CONFIG0 */
	devpriv->dux_commands[2] = 0x80; /* CONFIG1: 2kHz sampling rate */
	devpriv->dux_commands[3] = 0x00; /* CONFIG3: diff. channels off */
	devpriv->dux_commands[4] = 0;
	devpriv->dux_commands[5] = 0;
	devpriv->dux_commands[6] = sysred;
	ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD);
	if (ret < 0)
		return ret;

	ret = usbduxsigma_receive_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD);
	if (ret < 0)
		return ret;

	/* 32 bits big endian from the A/D converter */
	val = be32_to_cpu(get_unaligned((__be32 *)(devpriv->insn_buf + 1)));
	val &= 0x00ffffff;	/* strip status byte */
	val ^= 0x00800000;	/* convert to unsigned */

	return (int)val;
}
Exemplo n.º 7
0
static int usbduxsigma_dio_insn_bits(struct comedi_device *dev,
				     struct comedi_subdevice *s,
				     struct comedi_insn *insn,
				     unsigned int *data)
{
	struct usbduxsigma_private *devpriv = dev->private;
	int ret;

	down(&devpriv->sem);

	comedi_dio_update_state(s, data);

	/* Always update the hardware. See the (*insn_config). */
	devpriv->dux_commands[1] = s->io_bits & 0xff;
	devpriv->dux_commands[4] = s->state & 0xff;
	devpriv->dux_commands[2] = (s->io_bits >> 8) & 0xff;
	devpriv->dux_commands[5] = (s->state >> 8) & 0xff;
	devpriv->dux_commands[3] = (s->io_bits >> 16) & 0xff;
	devpriv->dux_commands[6] = (s->state >> 16) & 0xff;

	ret = usbbuxsigma_send_cmd(dev, USBDUXSIGMA_DIO_BITS_CMD);
	if (ret < 0)
		goto done;
	ret = usbduxsigma_receive_cmd(dev, USBDUXSIGMA_DIO_BITS_CMD);
	if (ret < 0)
		goto done;

	s->state = devpriv->insn_buf[1] |
		   (devpriv->insn_buf[2] << 8) |
		   (devpriv->insn_buf[3] << 16);

	data[1] = s->state;
	ret = insn->n;

done:
	up(&devpriv->sem);

	return ret;
}
Exemplo n.º 8
0
static int usbduxsigma_ai_cmd(struct comedi_device *dev,
			      struct comedi_subdevice *s)
{
	struct usbduxsigma_private *devpriv = dev->private;
	struct comedi_cmd *cmd = &s->async->cmd;
	unsigned int len = cmd->chanlist_len;
	uint8_t muxsg0 = 0;
	uint8_t muxsg1 = 0;
	uint8_t sysred = 0;
	int ret;
	int i;

	down(&devpriv->sem);

	if (devpriv->high_speed) {
		/*
		 * every 2 channels get a time window of 125us. Thus, if we
		 * sample all 16 channels we need 1ms. If we sample only one
		 * channel we need only 125us
		 */
		unsigned int interval = usbduxsigma_chans_to_interval(len);

		devpriv->ai_interval = interval;
		devpriv->ai_timer = cmd->scan_begin_arg / (125000 * interval);
	} else {
		/* interval always 1ms */
		devpriv->ai_interval = 1;
		devpriv->ai_timer = cmd->scan_begin_arg / 1000000;
	}

	for (i = 0; i < len; i++) {
		unsigned int chan  = CR_CHAN(cmd->chanlist[i]);

		create_adc_command(chan, &muxsg0, &muxsg1);
	}

	devpriv->dux_commands[1] = devpriv->ai_interval;
	devpriv->dux_commands[2] = len;  /* num channels per time step */
	devpriv->dux_commands[3] = 0x12; /* CONFIG0 */
	devpriv->dux_commands[4] = 0x03; /* CONFIG1: 23kHz sample, delay 0us */
	devpriv->dux_commands[5] = 0x00; /* CONFIG3: diff. channels off */
	devpriv->dux_commands[6] = muxsg0;
	devpriv->dux_commands[7] = muxsg1;
	devpriv->dux_commands[8] = sysred;

	ret = usbbuxsigma_send_cmd(dev, USBBUXSIGMA_AD_CMD);
	if (ret < 0) {
		up(&devpriv->sem);
		return ret;
	}

	devpriv->ai_counter = devpriv->ai_timer;

	if (cmd->start_src == TRIG_NOW) {
		/* enable this acquisition operation */
		devpriv->ai_cmd_running = 1;
		ret = usbduxsigma_submit_urbs(dev, devpriv->ai_urbs,
					      devpriv->n_ai_urbs, 1);
		if (ret < 0) {
			devpriv->ai_cmd_running = 0;
			up(&devpriv->sem);
			return ret;
		}
		s->async->inttrig = NULL;
	} else {	/* TRIG_INT */
		s->async->inttrig = usbduxsigma_ai_inttrig;
	}

	up(&devpriv->sem);

	return 0;
}