コード例 #1
0
/* interrupt work handler */
static void stmvl6180_work_handler(struct work_struct *work)
{
	struct stmvl6180_data *data = gp_vl6180_data;
	int ret = 0;
	uint8_t to_startPS = 0;
	uint8_t range_status=0, range_start=0;

	mutex_lock(&data->work_mutex);

	if (data->enable_ps_sensor == 1) {

		/* vl6180_dbgmsg("Enter\n"); */
		data->rangeData.errorStatus = 0xFF; /* to reset the data, should be set by API */
		VL6180x_RdByte(vl6180x_dev, RESULT_RANGE_STATUS, &range_status);
		VL6180x_RdByte(vl6180x_dev, SYSRANGE_START, &range_start);

		if (data->enableDebug) {
			vl6180_errmsg("RangeStatus as 0x%x,RangeStart: 0x%x\n",range_status,range_start);
		}
		if (range_start == 0 && (range_status & 0x01) == 0x01) {
			ret = VL6180x_RangeGetMeasurementIfReady(vl6180x_dev, &(data->rangeData));
			if (!ret && data->rangeData.errorStatus !=DataNotReady ) {
				if (data->ps_is_singleshot)
					to_startPS = 1;
				if (data->rangeData.errorStatus == 17)
					data->rangeData.errorStatus = 16;
				stmvl6180_ps_read_measurement(); /* to update data */
			}
		}
		//if (!ret)
		//	stmvl6180_ps_read_measurement(); /* to update data */
		if (to_startPS)
			VL6180x_RangeSetSystemMode(vl6180x_dev, MODE_START_STOP |  MODE_SINGLESHOT);

		/* restart timer */
		schedule_delayed_work(&data->dwork, msecs_to_jiffies((data->delay_ms)));

	    /* vl6180_dbgmsg("End\n"); */
	}

	mutex_unlock(&data->work_mutex);

	return;
}
コード例 #2
0
/*
 * Initialization function
 */
static int stmvl6180_init_client(struct stmvl6180_data *data)
{
	uint8_t id = 0, module_major = 0, module_minor = 0;
	uint8_t model_major = 0, model_minor = 0;
	uint8_t i = 0, val;

	vl6180_dbgmsg("Enter\n");

	/* Read Model ID */
	VL6180x_RdByte(vl6180x_dev, VL6180_MODEL_ID_REG, &id);
	vl6180_errmsg("read MODLE_ID: 0x%x\n", id);
	if (id == 0xb4) {
		vl6180_errmsg("STM VL6180 Found\n");
	} else if (id == 0) {
		vl6180_errmsg("Not found STM VL6180\n");
	}

	/* Read Model Version */
	VL6180x_RdByte(vl6180x_dev, VL6180_MODEL_REV_MAJOR_REG, &model_major);
	model_major &= 0x07;
	VL6180x_RdByte(vl6180x_dev, VL6180_MODEL_REV_MINOR_REG, &model_minor);
	model_minor &= 0x07;
	vl6180_errmsg("STM VL6180 Model Version : %d.%d\n", model_major, model_minor);

	/* Read Module Version */
	VL6180x_RdByte(vl6180x_dev, VL6180_MODULE_REV_MAJOR_REG, &module_major);
	VL6180x_RdByte(vl6180x_dev, VL6180_MODULE_REV_MINOR_REG, &module_minor);
	vl6180_errmsg("STM VL6180 Module Version : %d.%d\n", module_major, module_minor);

	/* Read Identification */
	printk("STM VL6180 Serial Numbe: ");
	for (i = 0; i <= (VL6180_FIRMWARE_REVISION_ID_REG - VL6180_REVISION_ID_REG); i++) {
		VL6180x_RdByte(vl6180x_dev, (VL6180_REVISION_ID_REG + i), &val);
		printk("0x%x-", val);
	}
	printk("\n");


	/* intialization */
	if (data->reset) {
		/* no need
		vl6180_dbgmsg("WaitDeviceBoot");
		VL6180x_WaitDeviceBooted(vl6180x_dev);
		*/

		/* only called if device being reset, otherwise data being overwrite */
		vl6180_dbgmsg("Init data!");
		VL6180x_InitData(vl6180x_dev); /* only called if device being reset */
		data->reset = 0;
	}
	/* set user calibration data - need to be called after VL6180x_InitData */
#ifdef CALIBRATION_FILE
	stmvl6180_read_calibration_file();
#endif

	vl6180_dbgmsg("End\n");

	return 0;
}
コード例 #3
0
/**
 * call in the main loop
 * when running under debugger it enable doing direct vl6180x reg access
 * After  breaking at entrance
 * change  the the local index/data and cmd variable to do what needed
 * reg_cmd -1 wr byte -2wr word -3 wr dword
 * reg_cmd 1 rd byte 2 rd word 3 rd dword
 * step to last statement before return and read variable to get rd result exit
 */
void debug_stuff(void) {
    int reg_cmd = 0;
    static uint32_t reg_data;
    static uint16_t reg_index;

    if (reg_cmd) {
        switch (reg_cmd) {
            case -1:
                VL6180x_WrByte(theVL6180xDev, reg_index, reg_data);
                debug("Wr B 0x%X = %d", reg_index, (int)reg_data);
                break;
            case -2:
                VL6180x_WrWord(theVL6180xDev, reg_index, reg_data);
                debug("Wr W 0x%X = %d", reg_index, (int) reg_data);
                break;

            case -3:
                VL6180x_WrDWord(theVL6180xDev, reg_index, reg_data);
                debug("WrDW 0x%X = %d", reg_index, (int)reg_data);
                break;

            case 1:
                reg_data = 0;
                VL6180x_RdByte(theVL6180xDev, reg_index, (uint8_t*) &reg_data);
                debug("RD B 0x%X = %d", reg_index, (int)reg_data);
                break;
            case 2:
                reg_data = 0;
                VL6180x_RdWord(theVL6180xDev, reg_index, (uint16_t*) &reg_data);
                debug("RD W 0x%X = %d", reg_index, (int)reg_data);
                break;

            case 3:
                VL6180x_RdDWord(theVL6180xDev, reg_index, &reg_data);
                debug("RD DW 0x%X = %d", reg_index, (int)reg_data);
                break;
            default:
                debug("Invalid command %d", reg_cmd);
                /* nothing to do*/
                ;
        }
    }
}
コード例 #4
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;
}