使用F1C200S从零制作掌机之触摸ns2009驱动

一、硬件

LC-PI-200S板载的NS2009的中断引脚有接到F1C200S的PE12。lichee nano板载的NS2009的中断引脚未接,驱动需要轮询处理,太麻烦了。

所以这里使用LC-PI-200S测试。

image-20240612220246298

image-20240612220437365

二、驱动

2.1 设备树

suniv-f1c100s.dtsi

		pio: pinctrl@1c20800 {
			......
			
			i2c0_pd_pins: i2c0-pd-pins {
				pins = "PD0", "PD12";
				function = "i2c0";
			};
		};
		
		i2c0: i2c@1c27000 {
			compatible = "allwinner,sun6i-a31-i2c";
			reg = <0x01c27000 0x400>;
			interrupts = <7>;
			clocks = <&ccu CLK_BUS_I2C0>;
			resets = <&ccu RST_BUS_I2C0>;
			pinctrl-names = "default";
			pinctrl-0 = <&i2c0_pd_pins>;
			status = "disabled";
			#address-cells = <1>;
			#size-cells = <0>;
		};

suniv-f1c100s-licheepi-nano.dts

&i2c0 {
	pinctrl-names = "default";
	pinctrl-0 = <&i2c0_pd_pins>;
	status = "okay";

	rtp@48 {
		compatible = "ti,tsc2007";
		reg = <0x48>;
		interrupt-parent = <&pio>;
		interrupts = <4 12 IRQ_TYPE_EDGE_FALLING>;
		gpios = <&pio 4 12 GPIO_ACTIVE_LOW>;
		pendown-gpio = <&pio 4 12 GPIO_ACTIVE_LOW>;
		ti,x-plate-ohms = <660>;
		wakeup-source;
		status = "okay";
	};
};

重新编译设备树后替换

make dtbs
cp arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dtb /media/wang/BOOT

2.2 配置驱动

linux内核中make menuconfig

Device Drivers  --->
	Input device support  --->
		[*]   Touchscreens  --->
			<*>   TSC2007 based touchscreens

image-20240613090852733

重新编译内核后替换

make
cp arch/arm/boot/zImage /media/wang/BOOT

2.3 配置tslib

buildroot目录下make menuconfig

Target packages  --->
	Libraries  --->
		Hardware handling  --->
			[*] tslib

image-20240613091107213

重新编译文件系统后替换

make
sudo rm /media/wang/rootfs -rf
sudo tar -xvf /output/images/rootfs.tar /media/wang/rootfs -C

三、修改LCD屏幕驱动

重新上电后未达到预期,屏幕无内容显示了。检查触摸设备树是否产生冲突。最后在设备树文件中发现,引脚冲突。需要将LCD驱动改为RGB565格式,省出触摸使用的引脚。

3.1 修改设备树

3.2 修改内核屏幕信息

在内核目录/drivers/gpu/drm/panel/panel-simple.c中,填写屏幕时序信息如下

static const struct panel_desc lg_lb070wv8 = {
	.modes = &lg_lb070wv8_mode,
	.num_modes = 1,
	.bpc = 16,
	.size = {
		.width = 151,
		.height = 91,
	},
	// .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
	.bus_format = MEDIA_BUS_FMT_RGB565_1X16,
};

3.3 编译

make
cp arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dtb /media/wang/BOOT
cp arch/arm/boot/zImage /media/wang/BOOT

四、配置tslib

重新启动设备,修改配置文件。sudo vi /etc/profile

export TSLIB_TSDEVICE=/dev/input/event0
export TSLIB_CALIBFILE=/etc/pointercal
export TSLIB_CONFFILE=/etc/ts.conf
export TSLIB_PLUGINDIR=/usr/lib/ts
export TSLIB_CONSOLEDEVICE=none
export TSLIB_FBDEVICE=/dev/fb0

source /etc/profile

五、测试

查看I2C0挂载的设备

i2cdetect -y 0

image-20240613223537302

校准触摸屏

ts_calibrate

image-20240613223806770

测试触摸屏

ts_print

image-20240613223629538

ts_test

image-20240613223828114

参考

https://wiki.sipeed.com/soft/Lichee/zh/Nano-Doc-Backup/build_sys/devicetree.html

https://blog.csdn.net/GJF712/article/details/126720236

https://blog.csdn.net/GJF712/article/details/126446054

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以提供一个简单的点灯驱动的实现,但需要注意的是,这只是一个示例代码,具体实现还需要根据硬件的具体情况进行调整。 首先,在驱动代码中需要定义一个 platform_driver 结构体,用于注册和注销驱动: ```c #include <linux/init.h> #include <linux/module.h> #include <linux/platform_device.h> #include <linux/io.h> MODULE_LICENSE("GPL"); #define DEVICE_NAME "my-leds" #define DRIVER_NAME "my-leds-driver" static void __iomem *led_addr; static int my_leds_probe(struct platform_device *pdev) { int ret = 0; struct resource *res; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "Failed to get resource\n"); return -ENODEV; } led_addr = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(led_addr)) { ret = PTR_ERR(led_addr); dev_err(&pdev->dev, "Failed to ioremap resource\n"); return ret; } return 0; } static int my_leds_remove(struct platform_device *pdev) { return 0; } static struct platform_driver my_leds_driver = { .probe = my_leds_probe, .remove = my_leds_remove, .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, }, }; static struct platform_device *my_leds_device; static int __init my_leds_init(void) { int ret = 0; my_leds_device = platform_device_alloc(DEVICE_NAME, 0); if (!my_leds_device) { ret = -ENOMEM; goto out; } ret = platform_device_add(my_leds_device); if (ret) { goto out; } ret = platform_driver_register(&my_leds_driver); if (ret) { platform_device_unregister(my_leds_device); goto out; } out: return ret; } static void __exit my_leds_exit(void) { platform_driver_unregister(&my_leds_driver); platform_device_unregister(my_leds_device); } module_init(my_leds_init); module_exit(my_leds_exit); ``` 上述代码中,`my_leds_probe` 函数用于初始化设备,`my_leds_remove` 函数用于注销设备。在 `my_leds_probe` 函数中,我们首先通过 `platform_get_resource` 函数获取设备资源,然后通过 `devm_ioremap_resource` 函数将资源映射到内存空间中。在本例中,我们假设设备资源是一段寄存器地址,可以通过 `led_addr` 来访问。 接下来,我们需要提供一个用户空间访问设备的接口。在驱动代码中,我们可以通过 `sysfs` 文件系统来实现。我们可以为设备提供一个属性文件,在用户空间通过该属性文件来控制设备。例如,我们可以为设备提供一个名为 `led_state` 的属性文件,用户空间可以通过该文件来控制 LED 灯的状态: ```c static ssize_t led_state_show(struct device *dev, struct device_attribute *attr, char *buf) { u32 val; val = readl(led_addr); return snprintf(buf, PAGE_SIZE, "%d\n", (val & 0x1)); } static ssize_t led_state_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { u32 val; if (kstrtouint(buf, 10, &val) == 0) { if (val) { writel(0x1, led_addr); } else { writel(0x0, led_addr); } } return count; } static DEVICE_ATTR_RW(led_state); ``` 上述代码中,`led_state_show` 函数用于从设备中读取 LED 灯的状态,`led_state_store` 函数用于向设备中写入 LED 灯的状态。我们使用 `readl` 和 `writel` 函数来读写寄存器地址,将 LED 灯的状态设置为 1 或 0。最后,我们将 `led_state` 属性文件注册到 `sysfs` 文件系统中,通过 `DEVICE_ATTR_RW` 宏来实现读写属性。 最后,在驱动代码中需要实现 `module_init` 和 `module_exit` 函数,用于初始化和注销驱动。我们可以通过 `platform_device_alloc` 函数来创建一个新的设备,通过 `platform_device_add` 函数将设备添加到系统中。然后,通过 `platform_driver_register` 函数来注册驱动,完成驱动的初始化。在注销驱动时,需要调用 `platform_driver_unregister` 和 `platform_device_unregister` 函数来注销驱动和设备。 这就是一个简单的点灯驱动的实现。需要注意的是,这只是一个示例代码,具体实现还需要根据硬件的具体情况进行调整。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值