嵌入式爱好者

T507为GPIO配置上拉和中断以检测外部电平变化

2023-11-29 10:10| 发布者: 听我说| 查看: 351| 评论: 0

类目: 知识库  >  T507系列产品     文档编号: 1216

以下示例是将GPIO配置成输入并上拉,当产生边沿时触发中断,在中断服务函数内会完成相应的操作
1、设备树节点
button {
			compatible = "gpio-button";
			donw-disp,gpio = <&pio PH 2 1 1 1 0>;
			linux,code = <194>;
		};

2、驱动源码
#include <linux/init.h> #include <linux/module.h> #include <linux/gpio.h> #include <linux/input.h> #include <linux/interrupt.h> #include <linux/of.h> #include <linux/of_gpio.h> #include <linux/device.h> #include <linux/platform_device.h> #include <signal.h> #include <sys/ioctl.h> #include <disp2/sunxi_display2.h> #include <sys/time.h> #define DRIVER_NAME "gpio_button_driver" struct gpio_button_data { int gpio; int irq; int keycode; bool is_down; struct input_dev *input; }; static irqreturn_t gpio_button_irq(int irq, void *dev_id) { struct gpio_button_data *data = dev_id; bool is_down = gpio_get_value(data->gpio) == 0; if (is_down != data->is_down) { data->is_down = is_down; // 触发输入事件 input_event(data->input, EV_KEY, data->keycode, is_down ? 1 : 0); input_sync(data->input); } return IRQ_HANDLED; } static int gpio_button_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *node = dev->of_node; struct gpio_button_data *data; int ret; data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); if (!data) { dev_err(dev, "Failed to allocate memory\n"); return -ENOMEM; } // data->gpio = of_get_gpio(node, 0); data->gpio = of_get_named_gpio(node, "donw-disp,gpio", 0); if (data->gpio < 0) { dev_err(dev, "Failed to get gpio\n"); return data->gpio; } ret = gpio_request(data->gpio, "my-gpio-button"); if (ret) { dev_err(dev, "Failed to request gpio\n"); return ret; } data->irq = gpio_to_irq(data->gpio); ret = request_irq(data->irq, gpio_button_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "my-gpio-button", data); if (ret) { dev_err(dev, "Failed to request IRQ\n"); goto free_gpio; } // 获取按键对应的键值 if (of_property_read_u32(node, "linux,code", &data->keycode)) { dev_err(dev, "Failed to get keycode\n"); ret = -EINVAL; goto free_irq; } // 初始化 input_dev 结构体 data->input = input_allocate_device(); if (!data->input) { dev_err(dev, "Failed to allocate input device\n"); ret = -ENOMEM; goto free_irq; } data->input->name = dev_name(dev); data->input->id.bustype = BUS_HOST; data->input->id.vendor = 0x0000; data->input->id.product = 0x0000; data->input->id.version = 0x0000; // 设置输入事件类型和代码 set_bit(EV_KEY, data->input->evbit); set_bit(data->keycode, data->input->keybit); // 注册输入设备 ret = input_register_device(data->input); if (ret) { dev_err(dev, "Failed to register input device\n"); goto free_input; } platform_set_drvdata(pdev, data); return 0; free_input: input_free_device(data->input); free_irq: free_irq(data->irq, data); free_gpio: gpio_free(data->gpio); return ret; } static int gpio_button_remove(struct platform_device *pdev) { struct gpio_button_data *data = platform_get_drvdata(pdev); input_unregister_device(data->input); free_irq(data->irq, data); gpio_free(data->gpio); return 0; } static const struct of_device_id gpio_button_of_match[] = { { .compatible = "gpio-button" }, {}, }; // MODULE_DEVICE_TABLE(of, gpio_button_of_match); static struct platform_driver gpio_button_driver = { .probe = gpio_button_probe, .remove = gpio_button_remove, .driver = { .name = DRIVER_NAME, .of_match_table = of_match_ptr(gpio_button_of_match), .owner = THIS_MODULE, }, }; static int __init gpio_button_init(void) { return platform_driver_register(&gpio_button_driver); } static void __exit gpio_button_exit(void) { platform_driver_unregister(&gpio_button_driver); } module_init(gpio_button_init); module_exit(gpio_button_exit); MODULE_AUTHOR("yanjianbo"); MODULE_DESCRIPTION("SW GPIO USER driver"); MODULE_LICENSE("GPL"); 3、应用源码 #include <termios.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <linux/input.h>


#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>

#include <signal.h>
#include <sys/ioctl.h>
#include <disp2/sunxi_display2.h>


#define EVENT_DEV "/dev/input/event8"

int set_brightness(int fd, int value) {
unsigned long args[3];
int err, i;
for(i = 0; i < 2; i++)
{
args[0] = i;
if(ioctl(fd, DISP_GET_OUTPUT_TYPE,args) == DISP_OUTPUT_TYPE_LCD)
{
args[1] = value;
args[2] = 0;
err = ioctl(fd, DISP_LCD_SET_BRIGHTNESS, args);
return err;
}
}
return -1;
}


int main()
{
int fd;
struct input_event ev;
int flag_disp=0;
int fd_disp = open("/dev/disp", O_RDONLY);
if (fd_disp < 0) {
printf("open /dev/disp failed\n");
return -1;
}
// 打开输入设备文件
fd = open(EVENT_DEV, O_RDONLY);
if (fd == -1) {
perror("Failed to open event device");
return 1;
}

while (1) {
// 读取输入事件
if (read(fd, &ev, sizeof(struct input_event)) < 0) {
perror("Failed to read event");
break;
}

// 判断是否为按键事件且按键状态改变
if (ev.type == EV_KEY && ev.value == 1) {
printf("in\n");
}

close(fd);
}

这个示例是通过EVENT事件将信息传递给应用,如果不需要,去掉input子系统的相关内容就行。

已解决

未解决

只是看看

最新评论

QQ|小黑屋| 飞凌嵌入式 ( 冀ICP备12004394号-1 )

GMT+8, 2025-7-1 18:55

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

返回顶部