Ник:
Пароль:

Контакты

E-mail: info@starterkit.ru
тел.: +7 922 680-21-73
тел.: +7 922 680-21-74
Телеграм: t.me/starterkit_ru

Способы оплаты

User Info


Добро пожаловать,
Guest

Регистрация или входРегистрация или вход
Потеряли пароль?Потеряли пароль?

Ник:
Пароль:

ПользователейПользователей:3
Поисковых ботовПоисковых ботов:3
ГостейГостей:1

ОбновитьПодробнееВсегоВсего:7
Форум » starterkit.ru » Embedded Linux
Прерывание на GPIO по заднему фронту
kruger
Добавлено 28.09.2010 00:02 Редактировалось 28.09.2010 00:16
0
Сообщение: 1
kruger
0

Пункты: 3936
Регистрация: 09.05.2010
Пол: Мужчина
Приветствую!!

Возникла необходимость обрабатывать прерывание на GPIO по заднему фронту (Плата - SK-AT91SAM9260-SIM508 ).

Проблема в том, что функция request_irq заканчивается успехом только в том случае если указать в параметрах прерывания IRQF_TRIGGER_NONE.
Во всех других случаях (IRQF_TRIGGER_FALLING, IRQF_TRIGGER_RISING, IRQF_TRIGGER_HIGH, IRGQ_TRIGGER_LOW) прерывание не устанавливается - система пишет:

Код
setting trigger mode 4 for irq 54 failed (gpio_irq_type+0x0/0x1c)


Привожу код своего драйвера:

Код
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <mach/gpio.h>

#define DCLK AT91_PIN_PA22

static irqreturn_t dclk_interrupt(int irq, void *dev_id)
{
printk(KERN_ALERT "dclk");
return IRQ_HANDLED;
}

static int irq_init(void)
{
at91_set_GPIO_periph(DCLK, 0);
at91_set_gpio_input(DCLK, 0);
at91_set_deglitch(DCLK, 1);
request_irq(DCLK, dclk_interrupt, IRQF_TRIGGER_LOW, "dclk", NULL);
return 0;
}

static int __init driver_init(void)
{
printk(KERN_ALERT "INFO: start driver init...\n");
irq_init();
return 0;
}

static void __exit driver_exit(void)
{
free_irq(DCLK, NULL);
printk(KERN_ALERT "INFO: driver exit");
}

module_init(driver_init);
module_exit(driver_exit);
MODULE_LICENSE("GPL");


Вопрос, возможно как-то заставить срабатывать прерывание только по заднему фронту? На крайний случай хотя бы по переднему.
Также хотелось бы, если кого нибудь не затруднить, увидеть пример использование аппаратного прерывания EXT2 или EXT3.
Спуститься к концу Подняться к началу
Персональная информация
Strijar
Добавлено 28.09.2010 15:16 Сообщение: 2
Strijar
Ранг
5

Группа: Клиенты
Пункты: 1618
Регистрация: 21.04.2009
Пол: Мужчина
Вот так у меня, работает:

Код

static irqreturn_t interrupt(int irq, drv_t *dev) {
if (gpio_get_value(dev->irq_pin)) {
schedule_work(&dev->work);
}

return IRQ_HANDLED;
}
...
irq_pin = irq_pins[i];
drv->irq_pin = irq_pin;

at91_set_gpio_input(irq_pin, 1);
at91_set_deglitch(irq_pin, 1);

irq = gpio_to_irq(irq_pin);

if (irq < 0) {
pr_err("cc1101: Unable to get irq numbe, error %d\n", irq);
return irq;
}

ret = request_irq(irq, &interrupt, IRQF_SHARED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "cc1101", drv);

Спуститься к концу Подняться к началу
Персональная информация
kruger
Добавлено 28.09.2010 19:06 Сообщение: 3
kruger
0

Пункты: 3936
Регистрация: 09.05.2010
Пол: Мужчина
После того как переписал по предложенному варианту Strijar, драйвер стал нормально регистрироваться в системе, но обработчик в таком случае не хочет никак реагировать на внешнее событие.
Хотя только стоит убрать IRQF_SHARED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, как тут же он начинает срабатывать.
Есть какие либо предложения ?
Спуститься к концу Подняться к началу
Персональная информация
Strijar
Добавлено 29.09.2010 14:00 Сообщение: 4
Strijar
Ранг
5

Группа: Клиенты
Пункты: 1618
Регистрация: 21.04.2009
Пол: Мужчина
Ну так в чем проблема? "Работает? - не трогай!" ;)
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 29.09.2010 16:18 Сообщение: 5
sasamy
4.71

Пункты: 83542
Регистрация: 14.08.2009
Цитата

Есть какие либо предложения ?


Убрать IRQF_SHARED, оставить
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING
Спуститься к концу Подняться к началу
Персональная информация
Форум » starterkit.ru » Embedded Linux