RK3566调试VL53L01

一、添加、编译驱动

1、从ST官方下载en.STSW-IMG005软件包,当前最新为1.0.4版本,软件包中有LinuxDriverMassMarket_1.0.7文件夹,继续打开LinuxDriverMassMarket_1.0.7\kernel\drivers\input\misc目录,将目录下的vl53L0X文件夹及内容拷贝到SDK的\kernel\drivers\input\misc目录下,修改misc目录下的Makefile及Kconfig添加VL53L0X。

Makefile末尾添加:

obj-$(CONFIG_STMVL53L0X)		+= vl53L0X/

Kconfig末尾添加:

config STMVL53L0X	  
	tristate "ST VL53L0x haptics support"
	depends on INPUT && I2C
	select INPUT_FF_MEMLESS
	select REGMAP_I2C
	help
	  Say Y to enable support for the ST VL53L0x haptics driver.

	  To compile this driver as a module, choose M here: the
	  module will be called vl53l0x-haptics.

添加再endif之前。

2、修改vl53L0X目录下的Makefile,改为以下内容:

#
# Makefile for the vl53L0X drivers.
#

# Each configuration option enables a list of files.
FEATURE_USE_CCI := false
#FEATURE_USE_CCI := true

ifeq ($(FEATURE_USE_CCI), true)
ccflags-y	+= -Idrivers/input/misc/vl53L0X/inc -DCAMERA_CCI
else
ccflags-y	+= -Idrivers/input/misc/vl53L0X/inc -DSTM_TEST
ccflags-y	+= -Idrivers/input/misc/vl53L0X
endif

ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/io
ccflags-y += -Idrivers/media/platform/msm/camera_v2
ccflags-y += -Idrivers/media/platform/msm/camera_v2/common
ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/cci

SRCS := $(wildcard ./src/*.c)
OBJS = $(SRCS:.c=.o)

obj-$(CONFIG_STMVL53L0X)			+= stmvl53l0x.o
stmvl53l0x-objs				:= stmvl53l0x_module.o stmvl53l0x_module-i2c.o stmvl53l0x_module-cci.o src/vl53l0x_api_calibration.o src/vl53l0x_api_core.o src/vl53l0x_api_ranging.o src/vl53l0x_api_strings.o src/vl53l0x_api.o src/vl53l0x_platform.o src/vl53l0x_i2c_platform.o src/vl53l0x_port_i2c.o

不修改编译会报错。

3、DTS文件中添加设备节点,需根据电路图确定VL53L01传感器是挂在那个i2c总线上,比如I2C2总线上,需在I2C2节点下方增加vl53l01的节点:

	vl53l0x: vl53l0x@29 {
		compatible = "st,stmvl53l0";
		reg = <0x29>;
		
		status = "okay";
	};

4、进入SDK的kernel目录下,执行make menuconfig ARCH=arm64修改内核配置文件,添加 ST VL53L0x xxx

RK3566调试VL53L01_第1张图片

 然后选择save,然后Exit,然后执行cp .config arch/arm64/configs/rockchip_linux_defconfig保存配置文件,然后重新编译内核,编译完成后烧写进主板。

5、接上传感器并将主板的日志打印串口连接到电脑的终端软件,然后启动主板,系统启动完成之后在终端输入dmesg | grep vl,查看vl53l01的加载日志:

[root@RK356X:/]# dmesg | grep stmvl
[    0.896764] stmvl53l0x_init: Enter
[    0.896781] stmvl53l0x_init_i2c: Enter
[    0.896824] stmvl53l0x_init_i2c: End with rc:-22
[    0.896839] stmvl53l0x_init: 1986 failed with -22
[    0.896849] stmvl53l0x_init: End
[    1.021873] stmvl53l0x_probe: Enter
[    1.021899] stmvl53l0x_parse_vdd: Enter
[    1.021919] stmvl53l0 2-0029: Looking up vdd-supply from device tree
[    1.021926] stmvl53l0 2-0029: Looking up vdd-supply property in node /i2c@fe5b0000/vl53l0x@29 failed
[    1.021953] stmvl53l0 2-0029: 2-0029 supply vdd not found, using dummy regulator
[    1.022028] stmvl53l0 2-0029: Linked as a consumer to regulator.0
[    1.022043] stmvl53l0x_parse_vdd: End
[    1.022056] stmvl53l0x_setup: Enter
[    1.022220] stmvl53l0x_poll_thread(758) : Starting Polling thread
[    1.022524] stmvl53l0x_setup: Misc device registration name:2-0029
[    1.022660] stmvl53l0x_setup: support ver. 1.0.5 enabled
[    1.022676] stmvl53l0x_setup: End
[    1.022678] stmvl53l0x_probe: End

经过实际测试,无论传感器与主板连接与否,都是这些日志,所以不能通过启动日志判断传感器是否正常连接。

6、可通过i2c tool工具查看传感器是否连接,命令终端输入i2cdetect -y 2即可查看i2c2总线上挂载的设备,如果传感器连接正常即可看到有0x29地址的设备。

7、测试传感器读取距离值

使用SDK的编译工具编译LinuxDriverMassMarket_1.0.7\kernel目录下的vl53l0x_test应用,编译成功后将执行文件推送到主板,然后运行,正常情况即可看到日志打印距离值,由于没有进行传感器校准,所以读取的距离值和实际距离值有偏差。

运行vl53l01x_test的日志

[root@RK356X:/userdata/bin]# ./vl53l0x_test 
[  175.411550] VL53L0X_GetDeviceInfo:
[  175.420316] Device Name : VL53L0X ES1 or later
[  175.420355] Device Type : VL53L0X
[  175.420363] Device ID : VL53L0C
[  175.420370] Product type: 238
[  175.420378] ProductRevisionMajor : 1
[  175.420385] ProductRevisionMinor : 1
[  175.420391] Call of VL53L0X_StaticInit
[  175.497162] Call of VL53L0X_SetDeviceMode
[  175.501836] DeviceMode:0x1, interMeasurems:30==
[  175.503118] Configure Long Ranging
[  175.503555] Set Timing Budget = 26000
Range:  45, Error:0, SigRate_mcps:1744896, AmbRate_mcps:   1536

 8、中断或查询模式

stmvl53l0x_module.cwe文件中有#define USE_INT宏定义用于定义使用中断模式或查询模式读取寄存器状态,如果取消USE_INT的注释,则使用中断模式,使用中断模式需要连接传感器的INT管脚到处理器的GPIO上。

二、修改驱动

1、通过宏定义开启或关闭日志打印,需要修改下stmvl53l0x.h文件:

#define DEBUG
#define vl53l0x_dbgmsg(str, args...)	\
	pr_err("%s: " str, __func__, ##args)
#define vl53l0x_errmsg(str, args...) \
	pr_err("%s: " str, __func__, ##args)

改为:

#define DEBUG

#ifdef DEBUG
#define vl53l0x_dbgmsg(str, args...)	\
	pr_err("%s: " str, __func__, ##args)
#define vl53l0x_errmsg(str, args...) \
	pr_err("%s: " str, __func__, ##args)
#else
#define vl53l0x_dbgmsg(str, args...)	\
	(void)0
#define vl53l0x_errmsg(str, args...) \
	(void)0
#endif

如果想关闭日志打印,则注释#define DEBUG即可。

2、在stmvl53l0x_module-i2c.c文件的stmvl53l0x_probe()加入检测传感器是否连接的代码,通过读取传感器的ID号以判断传感器是否连接,在stmvl53l0x_parse_vdd(&i2c_object->client->dev, i2c_object);之后加入如下代码:

	/* read VL53L0X ID */
	
	Status = VL53L0X_RdByte(vl53l0x_data, VL53L0X_REG_IDENTIFICATION_MODEL_ID,
	&module_id);

	if( Status )
	{
		vl53l0x_dbgmsg("get module_id err:%d\n", Status );
	}
	else
	{
		vl53l0x_dbgmsg("module_id:%02X\n", module_id );
	}

3、中断模式的IRQ_NUM从DTS文件中解析

驱动默认注释了USE_INT (/* #define USE_INT */),即不使用中断模式,并且中断的GPIO号实在驱动中定义的,这样方便管脚的更换,可修改为从DTS文件中解析。

stmvl53l0x.h文件的struct stmvl53l0x_data{ }结构中增加irq_gpiounsigned和irq_gpio_flags两个变量:

struct stmvl53l0x_data {

	/* !

stmvl53l0x_module-i2c.c文件中增加#include

 stmvl53l0x_module-i2c.c文件中增加stmvl53l0x_parse_dt()函数:

static int stmvl53l0x_parse_dt(struct device *dev, struct stmvl53l0x_data *pdata)
{
	int ret = 0;
	struct device_node *np = dev->of_node;

	const  struct of_device_id *match;

	match=of_match_device(st_stmvl53l0x_dt_match,dev);
	if(!match){
		vl53l0x_errmsg("DTS Unable to find matchv device.");
		return -1; 
	}

	pdata->irq_gpio = of_get_named_gpio_flags(np, "st,irq-gpio", 0, &pdata->irq_gpio_flags);
	if (pdata->irq_gpio < 0){
		vl53l0x_errmsg("DTS Unable to get irq_gpio");
		ret = -1;
	}
	else
	{
		vl53l0x_dbgmsg("irq gpio:%d", pdata->irq_gpio);
	}

	return ret;
}

在stmvl53l0x_probe()函数中调用此函数:

static int stmvl53l0x_probe(struct i2c_client *client,
				   const struct i2c_device_id *id)
{
	int rc = 0;
	struct stmvl53l0x_data *vl53l0x_data = NULL;
	struct i2c_data *i2c_object = NULL;
	VL53L0X_Error Status = VL53L0X_ERROR_NONE;
	uint8_t module_id;

	vl53l0x_dbgmsg("Enter\n");

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) {
		rc = -EIO;
		return rc;
	}

	vl53l0x_data = kzalloc(sizeof(struct stmvl53l0x_data), GFP_KERNEL);
	if (!vl53l0x_data) {
		rc = -ENOMEM;
		return rc;
	}
	if (vl53l0x_data) {
		vl53l0x_data->client_object =
			kzalloc(sizeof(struct i2c_data), GFP_KERNEL);
		i2c_object = (struct i2c_data *)vl53l0x_data->client_object;
	}
	i2c_object->client = client;

	/* setup bus type */
	vl53l0x_data->bus_type = I2C_BUS;

	/* setup regulator */
	stmvl53l0x_parse_vdd(&i2c_object->client->dev, i2c_object);

	/* setup dt */
	stmvl53l0x_parse_dt(&i2c_object->client->dev, vl53l0x_data);

	/* read VL53L0X ID */
	
	Status = VL53L0X_RdByte(vl53l0x_data, VL53L0X_REG_IDENTIFICATION_MODEL_ID,
	&module_id);

	if( Status )
	{
		vl53l0x_dbgmsg("get module_id err:%d\n", Status );
	}
	else
	{
		vl53l0x_dbgmsg("module_id:%02X\n", module_id );
	}
		
	/* setup device name */
	vl53l0x_data->dev_name = dev_name(&client->dev);

	/* setup device data */
	dev_set_drvdata(&client->dev, vl53l0x_data);

	/* setup client data */
	i2c_set_clientdata(client, vl53l0x_data);

	
	/* setup other stuff */
	rc = stmvl53l0x_setup(vl53l0x_data);

	/* init default value */
	i2c_object->power_up = 0;

	vl53l0x_dbgmsg("End\n");
	return rc;
}

修改stmvl53l0x_module.c文件,

	gpio_request(IRQ_NUM, "vl53l0x_gpio_int");
	gpio_direction_input(IRQ_NUM);
	irq = gpio_to_irq(IRQ_NUM);

	if (irq < 0) {
		vl53l0x_errmsg("filed to map GPIO: %d to interrupt:%d\n",
			IRQ_NUM, irq);

改为

	gpio_request( data->irq_gpio, "vl53l0x_gpio_int");
	gpio_direction_input(data->irq_gpio);
	irq = gpio_to_irq(data->irq_gpio);

	if (irq < 0) {
		vl53l0x_errmsg("filed to map GPIO: %d to interrupt:%d\n",
			data->irq_gpio, irq);

你可能感兴趣的:(linux外设驱动调试,vl53l01,linux,driver)