记一次移植GT9271无法正常通信

 移植汇顶的TP GT9271时,发现i2c通信不上,检查了TP的供电和复位脚及硬件连接,都没发现问题,然后发现内核有如下的报错信息。

[49533.829164] gpio-272 (goodix_ts_int): _gpiod_direction_output_raw: tried to set a GPIO tied to an IRQ as output
[49533.849418] goodix-ts 3-005d: I2c read failed,dev:5d,reg:8047,size:1
[49533.849433] goodix-ts 3-005d: GTP i2c test failed time 1
[49533.871495] goodix-ts 3-005d: I2c read failed,dev:5d,reg:8047,size:1
[49533.871510] goodix-ts 3-005d: GTP i2c test failed time 2
[49533.895621] goodix-ts 3-005d: I2c read failed,dev:5d,reg:8047,size:1
[49533.895634] goodix-ts 3-005d: GTP i2c test failed time 

但为什么设置io口为输出也报错呢 ,查看相应的代码

drivers/gpio/gpiolib.c

static int _gpiod_direction_output_raw(struct gpio_desc *desc, int value)
{
	struct gpio_chip *gc = desc->gdev->chip;
	int val = !!value;
	int ret;

	/* GPIOs used for IRQs shall not be set as output */
	if (test_bit(FLAG_USED_AS_IRQ, &desc->flags)) {
		gpiod_err(desc,
			  "%s: tried to set a GPIO tied to an IRQ as output\n",
			  __func__);
		return -EIO;
	}

	if (test_bit(FLAG_OPEN_DRAIN, &desc->flags)) {
		/* First see if we can enable open drain in hardware */
		ret = gpio_set_drive_single_ended(gc, gpio_chip_hwgpio(desc),
						  PIN_CONFIG_DRIVE_OPEN_DRAIN);
		if (!ret)
			goto set_output_value;
		/* Emulate open drain by not actively driving the line high */
		if (val)
			return gpiod_direction_input(desc);
	}
	else if (test_bit(FLAG_OPEN_SOURCE, &desc->flags)) {
		ret = gpio_set_drive_single_ended(gc, gpio_chip_hwgpio(desc),
						  PIN_CONFIG_DRIVE_OPEN_SOURCE);
		if (!ret)
			goto set_output_value;
		/* Emulate open source by not actively driving the line low */
		if (!val)
			return gpiod_direction_input(desc);
	} else {
		gpio_set_drive_single_ended(gc, gpio_chip_hwgpio(desc),
					    PIN_CONFIG_DRIVE_PUSH_PULL);
	}

set_output_value:
	if (!gc->set || !gc->direction_output) {
		gpiod_warn(desc,
		       "%s: missing set() or direction_output() operations\n",
		       __func__);
		return -EIO;
	}

	ret = gc->direction_output(gc, gpio_chip_hwgpio(desc), val);
	if (!ret)
		set_bit(FLAG_IS_OUT, &desc->flags);
	trace_gpio_value(desc_to_gpio(desc), 0, val);
	trace_gpio_direction(desc_to_gpio(desc), 0, ret);
	return ret;
}

原来,内核默认禁止中断设置成输出,这也合理,一般设置成中断模式的引脚,只需设置成输入模式,然后读取引脚的状态即可。

但为什么代码里将中断脚设置成输出呢。

查看规格书https://github.com/hadess/gt9xx

居然用中断脚来进行通信了 ,跟普通的中断脚不一样了。

但为什么高通/MTK他们用这份驱动没有问题了,原来他们用pinctrl的方式控制引脚状态,但展讯平台还没支持pinctrl这种方式,用的是普通的gpio模式,所以有这样的问题。那要怎么修改呢。

一种方式是先释放中断,拉低或拉高gpio后,重新设置成中断模式。

第二种方式是屏蔽_gpiod_direction_output_raw的返回,让代码跑下去。

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
根据引用\[1\],RT-Thread支持Modbus RTU、Modbus ASCII和Modbus TCP三种模式,但目前只支持Modbus RTU模式。另外,从机地址需要连续,并且起始地址从1开始。如果你的RT-Thread移植的freemodbus从站无法通信,可能有以下几个原因: 1. 配置错误:请确保你在移植过程中正确配置了FreeModbus相关参数。你可以参考引用\[2\]中提供的基于RT-Thread的freemodbus移植工程进行学习和参考。 2. 通信模式不匹配:请确认你的主机和从机使用的通信模式是一致的。如果主机使用的是Modbus RTU模式,那么从机也需要使用相同的模式。 3. 地址设置错误:请检查从机地址是否设置正确,并且起始地址是否从1开始。 如果你已经确认以上问题都没有出现,但仍然无法通信,可能需要进一步调试和排查。你可以参考引用\[3\]中提供的FreeModbus文档,了解更多关于FreeModbus的功能支持和使用方法。另外,你也可以联系RT-Thread开发团队及社区开发者,寻求他们的帮助和支持。他们的联系方式可以在引用\[1\]中找到。 #### 引用[.reference_title] - *1* [RT-Thread 之 移植 FreeModbus 协议栈( 同时支持主机和从机功能)](https://blog.csdn.net/hanhui22/article/details/108358924)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [MODBUS学习篇四------freemodbus的移植(rt-thread系统)](https://blog.csdn.net/weixin_42682108/article/details/112803053)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值