GPIO中断使用

1. GPIO作为中断使用;
在以前常见的GPIO作为中断使用的时候,一般做以下步骤即可:
* 设置GPIO复用功能为 一般的GPIO功能;
* 设置GPIO为input状态;
* 设置产生中断的方式;上升延,还是下降延;
* 设置中断控制器 enable GPIO_X位

在其他的平台或许你这样设置就没有什么问题了。但是在PXA 27x 系列中,你必须设置:
IPR0-IPR39 寄存器;来设置中断的优先级。

另外:我要提醒大家的是。GRER 和GFER 这两组寄存器用来设置GPIO的中断方式。
当我们设置为上升延中断 我们要将GRER寄存器对应的位设置为1,还必须将GFER的对应位设置为0。
如果都设置为1,那么就出现上升延或者下降延都会产生中断。

根据不同的应用模式选择不同的中断方式。
例如网卡就应该设置其中一种延方式触发。GRER和GFER的对应位不能同时设置为1。如果这样做了,驱动误认为收到或者发送了两次包。

例如:SD卡中断可以设置GRER和GFER的对应位都为1。这样插入卡和拔出卡就可以用同一个中断。
不需要使用两个GPIO中断来实现。

2. 一些特殊GPIO的设置方法;

这里描述的实际上是一种思路。在我实际的开发过程中我们用了GPIO 10来作为touch panel的数据读的pin。
当我们用模拟的SPI时序来读touch panel数据的时候: clk,din,busy,cs等都没有问题。读出来的数据就是有问题。
我们找了很长时间。发现我们设置GPIO脚的方法如下:
* 设置GPIO 复选功能为普通GPIO;
* 设置GPIO 为输入状态;
* 不用作中断模式;

尽管这样我们获取的数据还是有问题,我们用示波器测试GPIO 10有方波,
奇怪?难道是作为HZ_CLK了?我反复设置了GPIO的复选功能作为一般的GPIO功能都不管用?
那么到底问题出在那里呢?

原来是:OSCC 的TOUT_EN位,如果这一位设置了。不管复选功能怎么设置都是HZ_CLK功能。
并且程序能通过GPIO的寄存器读到数据的变化。

3. USB client  controller使用方法;
   这里要讲的实际上是硬件电路相关的内容。
  
   大家知道usb client实际上是有两种状态:
    * 空闲;
    * 插入到PC连接状态。

   那么这两种状态,我们怎么判断呢?
   这里一般都是通过PC的USB连接线上的5V来迫使一个3.3V电路导通到地。通过这个电压的改变来获取插入或者拔出的状态。

  
   在Intel给我们提供PXA 270的标准开发板(mainstone II)中有一个STF203-22的USBC 的filter 。这个小芯片成本可不低。
   他的作用不仅仅是filter。如果我们不想使用它,那么怎么做呢?当然我们有一个低成本方案。就是用1.5K电阻将D+这个信号线拉高。
   如果不使用这个电阻,我们可能会面临usbc 不停的复位问题。这是因为,USBC的状态中D-,D+同时为低超过2.5微秒,USBC就判断为复位。 

### RK3588 GPIO 中断配置及使用教程 #### 1. GPIO 中断基础 GPIO 中断是指当某个 GPIO 引脚的状态发生变化,触发 CPU 的中断处理机制。在 Linux 系统中,RK3588 的 GPIO 中断通过 `pinctrl` 驱动框架实现,并依赖设备树(Device Tree)来描述硬件资源[^2]。 #### 2. 设备树配置 为了使能 GPIO 中断功能,在设备树文件(DTS 文件)中需要定义对应的节点并指定中断属性: ```dts key_input: key-input { compatible = "key-input"; status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&key_gpio>; interrupts = <GIC_SPI 7 IRQ_TYPE_EDGE_FALLING>; /* 假设中断号为 7 */ }; ``` 上述代码片段中: - `compatible` 字段用于匹配驱动程序。 - `interrupts` 定义了中断源及其触发方式(如下降沿触发 `IRQ_TYPE_EDGE_FALLING` 或上升沿触发 `IRQ_TYPE_EDGE_RISING`)。具体数值需根据实际硬件手册填写[^3]。 #### 3. 驱动程序开发 以下是基于 RK3588 平台GPIO 中断驱动示例代码: ```c #include <linux/module.h> #include <linux/interrupt.h> #include <linux/platform_device.h> static irqreturn_t gpio_irq_handler(int irq, void *dev_id) { pr_info("Interrupt triggered on GPIO\n"); // 处理逻辑... return IRQ_HANDLED; } static int __init my_gpio_init(struct platform_device *pdev) { int ret, irq; irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "Failed to get interrupt resource\n"); return irq; } ret = request_irq(irq, gpio_irq_handler, IRQF_TRIGGER_FALLING | IRQF_SHARED, "my_gpio_irq", NULL); if (ret) { dev_err(&pdev->dev, "Failed to register IRQ handler\n"); return ret; } pr_info("GPIO Interrupt driver initialized successfully.\n"); return 0; } static const struct of_device_id my_gpio_match[] = { { .compatible = "key-input" }, {}, }; static struct platform_driver my_gpio_driver = { .probe = my_gpio_init, .driver = { .name = "my_gpio", .of_match_table = my_gpio_match, }, }; module_platform_driver(my_gpio_driver); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Your Name"); MODULE_DESCRIPTION("Example GPIO Interrupt Driver for RK3588"); ``` 此代码实现了以下功能: - 使用 `request_irq()` 函数注册中断处理函数 `gpio_irq_handler`。 - 设置中断触发条件为下降沿触发 (`IRQF_TRIGGER_FALLING`)。 - 在平台驱动探针函数 `my_gpio_init` 中初始化中断资源[^4]。 #### 4. 测试与调试 完成驱动加载后,可通过以下命令测试中断响应情况: ```bash echo "Testing GPIO Interrupt..." cat /proc/interrupts ``` 观察目标中断编号是否有计数变化,验证中断是否正常工作[^5]。 --- ####
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值