Beispiel #1
0
ComediAnalogOutputSoftCal::ComediAnalogOutputSoftCal(const char *deviceFile, uint outputSubdevice,
                                                     uint writeChannel, double outputConversionFactor,
                                                     uint aref, bool resetOutput)
        : ComediAnalogIOSoftCal(deviceFile, outputSubdevice, &writeChannel, 1, PLUS_MINUS_TEN, aref),
          m_outputConversionFactor(outputConversionFactor), m_resetOutput(resetOutput)
{
        Logger(Debug, "ComediAnalogOutputSoftCal::ComediAnalogOutputSoftCal()\n");
        int flag = comedi_get_softcal_converter(m_subdevice, m_channels[0], m_range,
                        COMEDI_FROM_PHYSICAL, m_calibration, &m_converter);
        if (flag != 0) {
                Logger(Critical, "comedi_get_softcal_converter: %s.\n", comedi_strerror(comedi_errno()));
                throw "Error in comedi_get_softcal_converter()";
        }
#ifdef TRIM_ANALOG_OUTPUT
        // get physical data range for subdevice (min, max, phys. units)
        m_dataRange = comedi_get_range(m_device, m_subdevice, m_channels[0], m_range);
        Logger(Debug, "Range for 0x%x (%s):\n\tmin = %g\n\tmax = %g\n", m_dataRange,
                        (m_dataRange->unit == UNIT_volt ? "volts" : "milliamps"),
                        m_dataRange->min, m_dataRange->max);
        if(m_dataRange == NULL) {
                Logger(Critical, "comedi_get_range: %s.\n", comedi_strerror(comedi_errno()));
                throw "Error in comedi_get_range()";
        }
#endif
}
Beispiel #2
0
/**
 * facq_comedi_misc_test_period:
 * @dev: A comedi_t device.
 * @subindex: The subdevice index.
 * @n_channels: The number of channels in the chanlist.
 * @period: The sampling period in nanoseconds.
 * @err: a #GError.
 *
 * Checks if the sampling period is supported by the subdevice.
 *
 * Returns: %TRUE if the period is supported %FALSE in other case.
 */
gboolean facq_comedi_misc_test_period(comedi_t *dev,guint subindex,guint n_channels,guint period,GError **err)
{
	comedi_cmd *cmd = facq_comedi_misc_cmd_new(subindex);

	if( comedi_get_cmd_generic_timed(dev,
					 subindex,
					 cmd,
					 n_channels,
					 period) < 0){
		g_set_error_literal(err,FACQ_COMEDI_MISC_ERROR,
			FACQ_COMEDI_MISC_ERROR_FAILED,
				comedi_strerror(comedi_errno()));
		g_free(cmd);
		return FALSE;
	}
	if(cmd->scan_begin_arg != period){
		g_set_error(err,FACQ_COMEDI_MISC_ERROR,
			FACQ_COMEDI_MISC_ERROR_FAILED,
				"Period not supported try %u instead",
					cmd->scan_begin_arg);
		g_free(cmd);
		return FALSE;
	}
	g_free(cmd);
	return TRUE;
}
Beispiel #3
0
static comedi_polynomial_t *facq_comedi_misc_get_polynomial_hard(comedi_t *dev,guint subindex,const FacqChanlist *chanlist,GError **err)
{
	comedi_polynomial_t *p = NULL;
	guint iochans_n = 0, i = 0;
	guint chanspec = 0, chan = 0, range = 0;
	enum comedi_conversion_direction *dir = NULL;

	iochans_n = facq_chanlist_get_io_chans_n(chanlist);
	p = g_new0(comedi_polynomial_t,iochans_n);
	dir = facq_chanlist_get_comedi_conversion_direction_list(chanlist,NULL);
	for(i = 0;i < iochans_n;i++)
		chanspec = facq_chanlist_get_io_chanspec(chanlist,i);
		facq_chanlist_chanspec_to_src_values(chanspec,
				&chan,&range,
					NULL,NULL);
		if( comedi_get_hardcal_converter(dev,
		 			         subindex,
					         chan,
					         range,
					         dir[i],
					         &p[i]) < 0 ){
			g_set_error_literal(err,FACQ_COMEDI_MISC_ERROR,
				FACQ_COMEDI_MISC_ERROR_FAILED,
					comedi_strerror(comedi_errno()));
			g_free(dir);
			return NULL;
		}

	g_free(dir);
	return p;
}
Beispiel #4
0
/**
 * facq_comedi_misc_can_calibrate
 * @dev: A comedi_t device.
 * @subindex: The subdevice index.
 * @err: A #GError.
 *
 * Checks if a subdevice can be calibrated, in affirmative case returns
 * the supported calibration type.
 *
 * Returns: -1 in case of error, 0 if device can't be calibrated, 1 if
 * device can be soft-calibrated, 2 if device is hard-calibrated.
 */
gint facq_comedi_misc_can_calibrate(comedi_t *dev,guint subindex,GError **err)
{
	guint subd_flags = 0;
	GError *local_err = NULL;
	const gchar *driver_name = NULL;
	guint i = 0, drivers_len = 6;
	const gchar * const drivers[] =
        {
                "ni_pcimio", "ni_atmio",
                "ni_mio_cs", "cb_pcidas",
                "cb_pcidas64", "ni_labpc"
        };

	subd_flags = comedi_get_subdevice_flags(dev,subindex);
	if(subd_flags < 0){
		g_set_error_literal(&local_err,FACQ_COMEDI_MISC_ERROR,
				FACQ_COMEDI_MISC_ERROR_FAILED,
					comedi_strerror(comedi_errno()));
		goto error;
	}
	if(subd_flags & SDF_SOFT_CALIBRATED)
		return 1;
	else {
		driver_name = comedi_get_driver_name(dev);
		if(!driver_name){
			g_set_error_literal(&local_err,FACQ_COMEDI_MISC_ERROR,
				FACQ_COMEDI_MISC_ERROR_FAILED,
					comedi_strerror(comedi_errno()));
			goto error;
		}
		for(i = 0;i < drivers_len;i++)
			if(g_strcmp0(driver_name,drivers[i]) == 0)
				return 2;
	}
	return 0;

	error:
	if(local_err)
		g_propagate_error(err,local_err);
	return -1;
}
Beispiel #5
0
/**
 * facq_comedi_misc_get_bps:
 * @dev:A comedi_t device.
 * @subindex: The subdevice index.
 * @err: A #GError.
 *
 * Checks the subdevice flags to get the number of bytes per sample
 * used by the subdevice.
 *
 * Returns: The number of bytes per sample, or 0 in case of error.
 */
guint facq_comedi_misc_get_bps(comedi_t *dev,guint subindex,GError **err)
{
	guint subd_flags = 0;

	subd_flags = comedi_get_subdevice_flags(dev,subindex);
	if(subd_flags < 0){
		g_set_error_literal(err,FACQ_COMEDI_MISC_ERROR,
			FACQ_COMEDI_MISC_ERROR_FAILED,
				comedi_strerror(comedi_errno()));
		return 0;
	}
	if(subd_flags & SDF_LSAMPL)
		return sizeof(lsampl_t);
	else
		return sizeof(sampl_t);
}
Beispiel #6
0
/**
 * facq_comedi_misc_test_calibrated:
 * @dev: A comedi_t device.
 * @err: A #GError.
 *
 * Checks if the comedi device @dev, has been calibrated or not.
 * If a device was calibrated, a file with the calibration data
 * should exist. This function checks for this file.
 *
 * Returns: %TRUE if calibrated, %FALSE in other case.
 *
 * <para>
 * <note>
 * A malicious user can delete the file after the check is done,
 * but the comedi functions can deal with that. This is a simple
 * check.
 * </note>
 * </para>
 */
gboolean facq_comedi_misc_test_calibrated(comedi_t *dev,GError **err)
{
	gchar *cal_filename = NULL;
	gboolean ret = FALSE;

	cal_filename = comedi_get_default_calibration_path(dev);
	if(!cal_filename){
		g_set_error_literal(err,FACQ_COMEDI_MISC_ERROR,
					FACQ_COMEDI_MISC_ERROR_FAILED,
				comedi_strerror(comedi_errno()));
		g_free(cal_filename);
		return FALSE;
	}
	ret = g_file_test(cal_filename,G_FILE_TEST_EXISTS);
	g_free(cal_filename);
	return ret;
}
Beispiel #7
0
/**
 * facq_comedi_misc_get_min:
 * @dev: A comedi_t device.
 * @subindex: The subdevice index.
 * @chanlist: A #FacqChanlist object.
 * @err: A #GError.
 *
 * It's equal to facq_comedi_misc_get_max() but instead of returning the
 * maximum values, returns the minimum expected real values.
 *
 * Returns: A gdouble array. Free it with g_free():
 */
gdouble *facq_comedi_misc_get_min(comedi_t *dev,guint subindex,const FacqChanlist *chanlist,GError **err)
{
	guint iochans_n = 0, i = 0, chanspec = 0, chan = 0,range = 0;
	GError *local_err = NULL;
	gdouble *min = NULL;
	comedi_range *rng = NULL;

	g_return_val_if_fail(FACQ_IS_CHANLIST(chanlist),NULL);

	iochans_n = facq_chanlist_get_io_chans_n(chanlist);
	if(!iochans_n){
		g_set_error_literal(&local_err,
			FACQ_COMEDI_MISC_ERROR,
				FACQ_COMEDI_MISC_ERROR_FAILED,
					"The chanlist is empty");
		goto error;
	}
	min = g_new0(gdouble,iochans_n);
	for(i = 0;i < iochans_n;i++){
		chanspec = facq_chanlist_get_io_chanspec(chanlist,i);
		facq_chanlist_chanspec_to_src_values(chanspec,&chan,
						     &range,NULL,NULL);
		rng = comedi_get_range(dev,subindex,chan,range);
		if(!rng){
			g_set_error_literal(&local_err,
				FACQ_COMEDI_MISC_ERROR,
					FACQ_COMEDI_MISC_ERROR_FAILED,
						comedi_strerror(comedi_errno()));
		}
		min[i] = rng->min;
	}

	return min;
	
	error:
	if(min)
		g_free(min);
	if(local_err)
		g_propagate_error(err,local_err);
	return NULL;
}
Beispiel #8
0
/*
 * facq_comedi_misc_can_poll:
 * @dev: A comedi_t device.
 * @err: A #GError NOT optional, check it.
 *
 * Some drivers can make the kernel crash when using poll()
 * with them, we blacklist them here to know if we can do
 * poll() or not.
 *
 * Returns: %TRUE if you can do poll() or %FALSE in the other case.
 */
gboolean facq_comedi_misc_can_poll(comedi_t *dev,GError **err)
{
	const gchar * const drivers[] =
	{
		"comedi_test"
	};
	guint drivers_len = 1, i = 0;
	const gchar *driver_name = NULL;

	driver_name = comedi_get_driver_name(dev);
	if(!driver_name){
		g_set_error_literal(err,FACQ_COMEDI_MISC_ERROR,
			FACQ_COMEDI_MISC_ERROR_FAILED,
				comedi_strerror(comedi_errno()));
		return FALSE;
	}
	for(i = 0;i < drivers_len;i++)
		if(g_strcmp0(driver_name,drivers[i]) == 0)
			return FALSE;

	return TRUE;
}
Beispiel #9
0
bool ComediDigitalInput::initialise()
{
	// set as input channel
	if(!(comedi_dio_config(m_device,m_subdevice,m_channels[0],COMEDI_INPUT))==0)
		Logger(Critical, "ComediDigitalInput::initialise() - Config error: %s.\n",comedi_strerror(comedi_errno()));
	return true;	

}
Beispiel #10
0
bool ComediDigitalOutput::initialise()
{
	// set as output
	
	if(!(comedi_dio_config(m_device, m_subdevice, m_channels[0],COMEDI_OUTPUT))==0) {
		Logger(Critical, "ComediDigitalOutput::initialise() - Config error: %s.\n",comedi_strerror(comedi_errno()));
		return false;
	}
	if(!(comedi_set_routing(m_device, m_subdevice, m_channels[0], NI_PFI_OUTPUT_PFI_DO))==0) {
		Logger(Critical, "ComediDigitalOutput::initialise() - Routing error: %s.\n",comedi_strerror(comedi_errno()));
		return false;
	}
	return true;	

}
Beispiel #11
0
ComediAnalogInputSoftCal::ComediAnalogInputSoftCal(const char *deviceFile, uint inputSubdevice,
                                                   uint readChannel, double inputConversionFactor,
                                                   uint range, uint aref)
        : ComediAnalogIOSoftCal(deviceFile, inputSubdevice, &readChannel, 1, range, aref),
          m_inputConversionFactor(inputConversionFactor)
{
        Logger(Debug, "ComediAnalogInputSoftCal::ComediAnalogInputSoftCal()\n");
        int flag = comedi_get_softcal_converter(m_subdevice, m_channels[0], m_range,
                        COMEDI_TO_PHYSICAL, m_calibration, &m_converter);
        if (flag != 0) {
                Logger(Critical, "comedi_get_softcal_converter: %s.\n", comedi_strerror(comedi_errno()));
                throw "Error in comedi_get_softcal_converter()";
        }
}
Beispiel #12
0
bool ComediAnalogIOSoftCal::readCalibration()
{
        Logger(Debug, "ComediAnalogIOSoftCal::readCalibration()\n");
        m_calibrationFile = comedi_get_default_calibration_path(m_device);
        if (m_calibrationFile == NULL) {
                Logger(Critical, "comedi_get_default_calibration_path: %s.\n", comedi_strerror(comedi_errno()));
                return false;
        }
        else {
                Logger(Debug, "Using calibration file [%s].\n", m_calibrationFile);
        }

        m_calibration = comedi_parse_calibration_file(m_calibrationFile);
        if (m_calibration == NULL) {
                Logger(Critical, "comedi_parse_calibration_file: %s.\n", comedi_strerror(comedi_errno()));
                return false;
        }
        else {
                Logger(Debug, "Successfully parsed calibration file [%s].\n", m_calibrationFile);
        }
        return true;
}
Beispiel #13
0
/**
 * facq_comedi_misc_get_polynomial:
 * @dev: A comedi_t device.
 * @subindex: The subdevice index.
 * @chanlist: A #FacqChanlist object.
 * @err: A #GError.
 *
 * The functions makes some magic to obtain a per channel,
 * comedi_polynomial_t array. Each polynomial can be used
 * to convert from comedi data to physical samples.
 * See <function>comedi_to_physical()</function> for more 
 * info.
 *
 * Returns: An array of comedi_polynomial_t members. Free it
 * when it's no longer needed. %NULL in case of error.
 * The array length equals the number of I/O Channels in the
 * chanlist.
 */
comedi_polynomial_t *facq_comedi_misc_get_polynomial(comedi_t *dev,guint subindex,const FacqChanlist *chanlist,GError **err)
{
	guint subd_flags = 0;
	guint i = 0, chan = 0, range = 0, aref = 0, iochans_n = 0;
	guint chanspec = 0;
	gchar *cal_filename = NULL;
	comedi_calibration_t *cc = NULL;
	GError *local_err = NULL;
	comedi_polynomial_t *p = NULL;

	g_return_val_if_fail(FACQ_IS_CHANLIST(chanlist),NULL);
	iochans_n = facq_chanlist_get_io_chans_n(chanlist);
	if(iochans_n < 1){
		g_set_error_literal(&local_err,FACQ_COMEDI_MISC_ERROR,
			FACQ_COMEDI_MISC_ERROR_FAILED,
				"Chanlist is empty");
		goto error;
	}
	cal_filename = comedi_get_default_calibration_path(dev);
	if(!cal_filename){
		g_set_error_literal(&local_err,FACQ_COMEDI_MISC_ERROR,
			FACQ_COMEDI_MISC_ERROR_FAILED,
				comedi_strerror(comedi_errno()));
		goto error;
	}
	cc = comedi_parse_calibration_file(cal_filename);
	if(!cc){
		g_set_error_literal(&local_err,FACQ_COMEDI_MISC_ERROR,
			FACQ_COMEDI_MISC_ERROR_FAILED,
				comedi_strerror(comedi_errno()));
		goto error;
	}
	g_free(cal_filename);
	subd_flags = comedi_get_subdevice_flags(dev,subindex);
	if(subd_flags < 0){
		g_set_error_literal(&local_err,FACQ_COMEDI_MISC_ERROR,
			FACQ_COMEDI_MISC_ERROR_FAILED,
				comedi_strerror(comedi_errno()));
		goto error;
	}
	for(i = 0;i < iochans_n;i++){
		chanspec = facq_chanlist_get_io_chanspec(chanlist,i);
		facq_chanlist_chanspec_to_src_values(chanspec,
						     &chan,
						     &range,
						     &aref,
						     NULL);
		if( comedi_apply_parsed_calibration(dev,subindex,
						chan,
						range,
						aref,
						cc) < 0){
			g_set_error_literal(&local_err,FACQ_COMEDI_MISC_ERROR,
				FACQ_COMEDI_MISC_ERROR_FAILED,
					comedi_strerror(comedi_errno()));
			goto error;
		}
	}
	if(subd_flags & SDF_SOFT_CALIBRATED){
		p = facq_comedi_misc_get_polynomial_soft(dev,
							 subindex,
							 chanlist,
							 cc,
							 &local_err);
		comedi_cleanup_calibration(cc);
	}
	else {
		comedi_cleanup_calibration(cc);
		p = facq_comedi_misc_get_polynomial_hard(dev,
							 subindex,
							 chanlist,
							 &local_err);
	}
	if(!p)
		goto error;

	return p;

	error:
	if(cal_filename)
		g_free(cal_filename);
	if(cc)
		comedi_cleanup_calibration(cc);
	if(local_err)
		g_propagate_error(err,local_err);
	return NULL;
}
Beispiel #14
0
/**
 * facq_comedi_misc_test_chanlist:
 * @dev: A comedi_t device.
 * @subindex: A subdevice index.
 * @chanlist: A #FacqChanlist object.
 * @err: A #GError.
 *
 * Checks if the provided #FacqChanlist, @chanlist, can be used with
 * the subdevice @subindex, in the device @dev.
 *
 * Returns: %TRUE if supported %FALSE in other case.
 */
gboolean facq_comedi_misc_test_chanlist(comedi_t *dev,guint subindex,const FacqChanlist *chanlist,GError **err)
{
	GError *local_err = NULL;
	guint i = 0, len = 0, iochans_n = 0;
	guint n_channels = 0, n_ranges = 0, subd_flags = 0;
	guint chanspec = 0, chan = 0, range = 0, aref = 0, flags = 0;
	FacqChanDir dir = 0;
	gint subdevice_type = 0;

	g_return_val_if_fail(FACQ_IS_CHANLIST(chanlist),FALSE);
	len = facq_chanlist_get_length(chanlist);
	iochans_n = facq_chanlist_get_io_chans_n(chanlist);
	if(len < 1 || iochans_n == 0){
		g_set_error(&local_err,FACQ_COMEDI_MISC_ERROR,
				FACQ_COMEDI_MISC_ERROR_FAILED,
					"Chanlist needs at least one I/O channel");
		goto error;
	}
	subdevice_type = comedi_get_subdevice_type(dev,subindex);
	if(subdevice_type < 0){
		g_set_error_literal(&local_err,FACQ_COMEDI_MISC_ERROR,
				FACQ_COMEDI_MISC_ERROR_FAILED,
					comedi_strerror(comedi_errno()));
		goto error;
	}
	subd_flags = comedi_get_subdevice_flags(dev,subindex);
	if(subd_flags < 0){
		g_set_error_literal(&local_err,FACQ_COMEDI_MISC_ERROR,
				FACQ_COMEDI_MISC_ERROR_FAILED,
					comedi_strerror(comedi_errno()));
		goto error;
	}
	n_channels = comedi_get_n_channels(dev,subindex);
	if(n_channels < 0){
		g_set_error_literal(&local_err,FACQ_COMEDI_MISC_ERROR,
				FACQ_COMEDI_MISC_ERROR_FAILED,
					comedi_strerror(comedi_errno()));
		goto error;
	}
	for(i = 0;i < len;i++){
		chanspec = facq_chanlist_get_io_chanspec(chanlist,i);
		facq_chanlist_chanspec_to_src_values(chanspec,
							&chan,&range,
								&aref,&flags);
		dir = facq_chanlist_get_io_chan_direction(chanlist,i);
		n_ranges = comedi_get_n_ranges(dev,subindex,chan);
		if(n_ranges < 0){
			g_set_error_literal(&local_err,FACQ_COMEDI_MISC_ERROR,
				FACQ_COMEDI_MISC_ERROR_FAILED,
					comedi_strerror(comedi_errno()));
			goto error;	
		}
		if(!facq_comedi_misc_test_chanspec(n_channels,n_ranges,
						subd_flags,chan,range,
						aref,flags,dir,
						subdevice_type,
						&local_err))
			goto error;
	}
	return TRUE;

	error:
	if(local_err)
		g_propagate_error(err,local_err);
	return FALSE;
}