コード例 #1
0
void Sample_XTalkCalibrate(void) {
    VL6180xDev_t myDev;
    VL6180x_RangeData_t Range;

    int XTalkRate;
    int i, status;

    /* init device */
    MyDev_Init(myDev);
    status = Sample_Init(myDev);
    if( status <0 ){
        HandleError("Sample_Init fail");
    }
    /* run calibration */
    XTalkRate = Sample_XTalkRunCalibration(myDev);

    /*TODO when possible reset re-init device else set back required scaling/filter*/
    VL6180x_FilterSetState(myDev, 1);  // turn on wrap around filter again
    VL6180x_UpscaleSetScaling(myDev, 3);  // set scaling
    /* apply cross talk */
    status = VL6180x_SetXTalkCompensationRate(myDev, XTalkRate);
    if( status<0 ){ /* ignore warning but not error */
        HandleError("VL6180x_WrWord fail");
    }

    for( i=0; i< 10; i++){
        status = VL6180x_RangePollMeasurement(myDev, &Range);
        MyDev_ShowRange(myDev, Range.range_mm);
    }
}
コード例 #2
0
static int stmvl6180_start(struct stmvl6180_data *data, uint8_t scaling, init_mode_e mode)
{
	int rc = 0;
	vl6180_dbgmsg("Enter\n");

	/* Power up */
	rc = data->pmodule_func_tbl->power_up(&data->client_object, &data->reset);
	if (rc) {
		vl6180_errmsg("%d,error rc %d\n", __LINE__, rc);
		return rc;
	}
	/* init */
	rc = stmvl6180_init_client(data);
	if (rc) {
		vl6180_errmsg("%d, error rc %d\n", __LINE__, rc);
		data->pmodule_func_tbl->power_down(&data->client_object);
		return -EINVAL;
	}
	/* prepare */
	VL6180x_Prepare(vl6180x_dev);
	VL6180x_UpscaleSetScaling(vl6180x_dev, scaling);

	/* check mode */
	if (mode != NORMAL_MODE) {
#if VL6180x_WRAP_AROUND_FILTER_SUPPORT
		/* turn off wrap around filter */
		VL6180x_FilterSetState(vl6180x_dev, 0);
#endif
		VL6180x_SetXTalkCompensationRate(vl6180x_dev, 0);
		VL6180x_UpdateByte(vl6180x_dev, SYSRANGE_RANGE_CHECK_ENABLES,
						~RANGE_CHECK_RANGE_ENABLE_MASK, 0);

	}
	if (mode == OFFSETCALIB_MODE)
		VL6180x_SetOffsetCalibrationData(vl6180x_dev, 0);


	/* start - single shot mode */
	VL6180x_RangeSetSystemMode(vl6180x_dev, MODE_START_STOP|MODE_SINGLESHOT);
	data->ps_is_singleshot = 1;
	data->enable_ps_sensor = 1;

	/* enable work handler */
	stmvl6180_schedule_handler(data);

	vl6180_dbgmsg("End\n");

	return rc;
}
コード例 #3
0
/*
 * misc device file operation functions
 */
static int stmvl6180_ioctl_handler(struct file *file,
				unsigned int cmd, unsigned long arg, void __user *p)
{
	int rc = 0;
	unsigned int xtalkint = 0;
	int8_t offsetint = 0;
	struct stmvl6180_data *data = gp_vl6180_data;
	struct stmvl6180_register reg;

	if (!data)
		return -EINVAL;

	vl6180_dbgmsg("Enter enable_ps_sensor:%d\n", data->enable_ps_sensor);
	switch (cmd) {
	/* enable */
	case VL6180_IOCTL_INIT:
		pr_err("%s: VL6180_IOCTL_INIT\n", __func__);
		/* turn on tof sensor only if it's not enabled by other client */
		if (data->enable_ps_sensor == 0) {
			/* to start */
			stmvl6180_start(data, 3, NORMAL_MODE);
		} else
			rc = -EINVAL;
		break;
	/* crosstalk calibration */
	case VL6180_IOCTL_XTALKCALB:
		vl6180_dbgmsg("VL6180_IOCTL_XTALKCALB\n");
		/* turn on tof sensor only if it's not enabled by other client */
		if (data->enable_ps_sensor == 0) {
			/* to start */
			stmvl6180_start(data, 3, XTALKCALIB_MODE);
		} else
			rc = -EINVAL;
		break;
	/* set up Xtalk value */
	case VL6180_IOCTL_SETXTALK:
		vl6180_dbgmsg("VL6180_IOCTL_SETXTALK\n");
		if (copy_from_user(&xtalkint, (unsigned int *)p, sizeof(unsigned int))) {
			vl6180_errmsg("%d, fail\n", __LINE__);
			return -EFAULT;
		}
		vl6180_dbgmsg("SETXTALK as 0x%x\n", xtalkint);
#ifdef CALIBRATION_FILE
		xtalk_calib = xtalkint;
		stmvl6180_write_xtalk_calibration_file();
#endif
		VL6180x_SetXTalkCompensationRate(vl6180x_dev, xtalkint);
		break;
	/* offset calibration */
	case VL6180_IOCTL_OFFCALB:
		vl6180_dbgmsg("VL6180_IOCTL_OFFCALB\n");
		if (data->enable_ps_sensor == 0) {
			/* to start */
			stmvl6180_start(data, 3, OFFSETCALIB_MODE);
		} else
			rc = -EINVAL;
		break;
	/* set up offset value */
	case VL6180_IOCTL_SETOFFSET:
		vl6180_dbgmsg("VL6180_IOCTL_SETOFFSET\n");
		if (copy_from_user(&offsetint, (int8_t *)p, sizeof(int8_t))) {
			vl6180_errmsg("%d, fail\n", __LINE__);
			return -EFAULT;
		}
		vl6180_dbgmsg("SETOFFSET as %d\n", offsetint);
#ifdef CALIBRATION_FILE
		offset_calib = offsetint;
		stmvl6180_write_offset_calibration_file();
#endif
		VL6180x_SetOffsetCalibrationData(vl6180x_dev, offsetint);
		break;
	/* disable */
	case VL6180_IOCTL_STOP:
		vl6180_errmsg("VL6180_IOCTL_STOP\n");
		/* turn off tof sensor only if it's enabled by other client */
		if (data->enable_ps_sensor == 1) {
			data->enable_ps_sensor = 0;
			/* to stop */
			stmvl6180_stop(data);
		}
		break;
	/* Get all range data */
	case VL6180_IOCTL_GETDATAS:
		vl6180_dbgmsg("VL6180_IOCTL_GETDATAS\n");
		if (copy_to_user((VL6180x_RangeData_t *)p, &(data->rangeData), sizeof(VL6180x_RangeData_t))) {
			vl6180_errmsg("%d, fail\n", __LINE__);
			return -EFAULT;
		}
		break;
	case VL6180_IOCTL_REGISTER:
		vl6180_dbgmsg("VL6180_IOCTL_REGISTER\n");
		if (copy_from_user(&reg, (struct stmvl6180_register *)p,
							sizeof(struct stmvl6180_register))) {
			vl6180_errmsg("%d, fail\n", __LINE__);
			return -EFAULT;
		}
		reg.status = 0;
		switch (reg.reg_bytes) {
		case(4):
			if (reg.is_read)
				reg.status = VL6180x_RdDWord(vl6180x_dev, (uint16_t)reg.reg_index,
											&reg.reg_data);
			else
				reg.status = VL6180x_WrDWord(vl6180x_dev, (uint16_t)reg.reg_index,
											reg.reg_data);
			break;
		case(2):
			if (reg.is_read)
				reg.status = VL6180x_RdWord(vl6180x_dev, (uint16_t)reg.reg_index,
											(uint16_t *)&reg.reg_data);
			else
				reg.status = VL6180x_WrWord(vl6180x_dev, (uint16_t)reg.reg_index,
											(uint16_t)reg.reg_data);			
			break;
		case(1):
			if (reg.is_read)
				reg.status = VL6180x_RdByte(vl6180x_dev, (uint16_t)reg.reg_index,
											(uint8_t *)&reg.reg_data);
			else
				reg.status = VL6180x_WrByte(vl6180x_dev, (uint16_t)reg.reg_index,
											(uint8_t)reg.reg_data);						
			break;
		default:
			reg.status = -1;

		}
		if (copy_to_user((struct stmvl6180_register *)p, &reg,
							sizeof(struct stmvl6180_register))) {
			vl6180_errmsg("%d, fail\n", __LINE__);
			return -EFAULT;
		}
		break;
	default:
		rc = -EINVAL;
		break;
	}
	return rc;
}
コード例 #4
0
static void stmvl6180_read_calibration_file(void)
{
	struct file *f;
	char buf[8];
	mm_segment_t fs;
	int i, is_sign = 0;

	if(gp_vl6180_data->offset_buf.file_opened == true) {
		vl6180_dbgmsg("offset_calib as %d\n",
				gp_vl6180_data->offset_buf.value);
		VL6180x_SetOffsetCalibrationData(vl6180x_dev,
				gp_vl6180_data->offset_buf.value);
	} else {
		f = filp_open("/persist/calibration/offset", O_RDONLY, 0);
		if (f != NULL && !IS_ERR(f) && f->f_dentry != NULL) {
			fs = get_fs();
			set_fs(get_ds());
			/* init the buffer with 0 */
			for (i = 0; i < 8; i++)
				buf[i] = 0;
			f->f_op->read(f, buf, 8, &f->f_pos);
			set_fs(fs);
			vl6180_dbgmsg("offset as:%s, buf[0]:%c\n", buf, buf[0]);
			offset_calib = 0;
			for (i = 0; i < 8; i++) {
				if (i == 0 && buf[0] == '-')
					is_sign = 1;
				else if (buf[i] >= '0' && buf[i] <= '9')
					offset_calib = offset_calib * 10 + (buf[i] - '0');
				else
					break;
			}
			if (is_sign == 1)
				offset_calib = -1 * offset_calib;
			vl6180_dbgmsg("file open offset_calib as %d\n", offset_calib);
			gp_vl6180_data->offset_buf.file_opened = true;
			gp_vl6180_data->offset_buf.value = offset_calib;
			VL6180x_SetOffsetCalibrationData(vl6180x_dev, offset_calib);
			filp_close(f, NULL);
		} else {
			gp_vl6180_data->offset_buf.file_opened = true;
			gp_vl6180_data->offset_buf.value = 0;
			vl6180_errmsg("no offset calibration file exist!\n");
		}
	}
	is_sign = 0;
	if(gp_vl6180_data->xtalk_buf.file_opened == true) {
		vl6180_dbgmsg("xtalk_calib as %d\n",
				gp_vl6180_data->xtalk_buf.value);
		/* set up threshold ignore */
		if ((gp_vl6180_data->xtalk_buf.value+13) < 64 )
			VL6180x_WrWord(vl6180x_dev, SYSRANGE_RANGE_IGNORE_THRESHOLD, 64); /* 0.5Mcps */
		else
			VL6180x_WrWord(vl6180x_dev, SYSRANGE_RANGE_IGNORE_THRESHOLD, (gp_vl6180_data->xtalk_buf.value+13)); /* +0.1Mcps */
		VL6180x_WrByte(vl6180x_dev, SYSRANGE_RANGE_IGNORE_VALID_HEIGHT, 100);
		VL6180x_UpdateByte(vl6180x_dev, SYSRANGE_RANGE_CHECK_ENABLES,
						~RANGE_CHECK_RANGE_ENABLE_MASK, RANGE_CHECK_RANGE_ENABLE_MASK);
		/* setup xtalk compensation rate */
		VL6180x_SetXTalkCompensationRate(vl6180x_dev, gp_vl6180_data->xtalk_buf.value);
	} else {
		f = filp_open("/persist/calibration/xtalk", O_RDONLY, 0);
		if (f != NULL && !IS_ERR(f) && f->f_dentry != NULL) {
			fs = get_fs();
			set_fs(get_ds());
			/* init the buffer with 0 */
			for (i = 0; i < 8; i++)
				buf[i] = 0;
			f->f_op->read(f, buf, 8, &f->f_pos);
			set_fs(fs);
			vl6180_dbgmsg("xtalk as:%s, buf[0]:%c\n", buf, buf[0]);
			xtalk_calib = 0;
			for (i = 0; i < 8; i++) {
				if (i == 0 && buf[0] == '-')
					is_sign = 1;
				else if (buf[i] >= '0' && buf[i] <= '9')
					xtalk_calib = xtalk_calib * 10 + (buf[i] - '0');
				else
					break;
			}
			if (is_sign == 1)
				xtalk_calib = -1 * xtalk_calib;
			vl6180_dbgmsg("file open xtalk_calib as %d\n", xtalk_calib);
			gp_vl6180_data->xtalk_buf.file_opened = true;
			gp_vl6180_data->xtalk_buf.value = xtalk_calib;
			/* set up threshold ignore */
			if ((xtalk_calib+13) < 64 )
				VL6180x_WrWord(vl6180x_dev, SYSRANGE_RANGE_IGNORE_THRESHOLD, 64); /* 0.5Mcps */
			else
				VL6180x_WrWord(vl6180x_dev, SYSRANGE_RANGE_IGNORE_THRESHOLD, (xtalk_calib+13)); /* +0.1Mcps */
			VL6180x_WrByte(vl6180x_dev, SYSRANGE_RANGE_IGNORE_VALID_HEIGHT, 100);
			VL6180x_UpdateByte(vl6180x_dev, SYSRANGE_RANGE_CHECK_ENABLES,
							~RANGE_CHECK_RANGE_ENABLE_MASK, RANGE_CHECK_RANGE_ENABLE_MASK);
			/* setup xtalk compensation rate */
			VL6180x_SetXTalkCompensationRate(vl6180x_dev, xtalk_calib);
			filp_close(f, NULL);
		} else {
			gp_vl6180_data->xtalk_buf.file_opened = true;
			gp_vl6180_data->xtalk_buf.value = XTALK_CALIBRATION_DEFAULT;
			vl6180_errmsg("no xtalk calibration file exist!\n");
		}
	}
	return;
}