2010-09-13 06:35:02 GPIO and timers
Shyam sundar (INDIA)
Message: 93381
Hello world,
There will be a signal which remains high.This i will be connecting to the GPIO pin.I need detect a whether the signal went low for more than 125ms or not.
What kind of timers can I use for this to be impemented?
QuoteReplyEditDelete
2010-09-13 07:19:38 Re: GPIO and timers
Aaron Wu (CHINA)
Message: 93382
docs.blackfin.uclinux.org/doku.php?id=linux-kernel:high-resolution-timer
docs.blackfin.uclinux.org/doku.php?id=linux-kernel:timers
QuoteReplyEditDelete
2010-09-13 13:06:05 Re: GPIO and timers
Mike Frysinger (UNITED STATES)
Message: 93386
you might be able to utilize a pwm/gptimer pin
docs.blackfin.uclinux.org/doku.php?id=linux-kernel:drivers:gptimers
QuoteReplyEditDelete
2010-09-15 05:53:47 Re: GPIO and timers
Shyam sundar (INDIA)
Message: 93463
I think the function get_gptimer_pwidth(TIMER5_id) will look for a transition on the line before finding the width ie if the line is initially high and then goes low, then to calculate the width of the pulse the line has to go high again. Correct me if I am wrong.
In my experiment,there are two cases that can happen on the GPIO line
Case one, the line can go from high to low and remain in that state unless some external command is issued to make it high.
Case two,the line can go from high to low and remain in the low state for around 130ms and goes back to high state.
These are two different events which i should able to detect. So i think gptimers may not help me in this case.
I want to use a GPIO pin which will create a interrupt on falling edge.In the GPIO ISR I want to invoke a 130 ms timer and exit. When the 130 ms timer expires, I can check the GPIO line and identify which event happened.
I am little clueless about where to place the following piece of code.Can I use the function ring_line_init_interrupt() to be called from the user space? How can i invoke the timer in the function ringline_detect_entry() ?
#include <linux/interrupt.h>
#define INTERRUPT_NUMBER IRQ_PF5
#define DRIVER_NAME "SMS_CALL_DETECT"
static irqreturn_t ringline_detect_entry(int irq, void *dev_id)
{
printk(KERN_INFO "Starting timer of 130 ms \n");
/*code for invoking timer to be added*/
return IRQ_HANDLED;
}
static int __init ring_line_init_interrupt(void)
{
int ret;
ret = request_irq(INTERRUPT_NUMBER, ringline_detect_entry, IRQF_TRIGGER_FALLING,DRIVER_NAME,NULL);
if (ret)
{
printk(KERN_WARNING "IRQ %d is not free \n", INTERRUPT_NUMBER);
return ret;
}
return 0;
}
void __exit ringline_detect_exit(void)
{
free_irq(INTERRUPT_NUMBER, NULL);
}
QuoteReplyEditDelete
2010-09-15 16:50:25 Re: GPIO and timers
Mike Frysinger (UNITED STATES)
Message: 93472
the gptimer API is merely hiding the variant differences. get_gptimer_pwidth returns the value in the PWIDTH MMR. if you want to know what that MMR value contains, review the gptimers HRM section.
QuoteReplyEditDelete
2010-09-20 00:30:46 Re: GPIO and timers
Shyam sundar (INDIA)
Message: 93622
If i want to write a driver for only PF5.
Do i need to add or modify anything in the following driver?
How can i know that an interrupt occurred in the user space?
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <asm/gpio.h>
#include <linux/interrupt.h>
#define INTERRUPT_NUMBER IRQ_PF5
#define DRIVER_NAME "INTERRUPT_PF5"
static irqreturn_t gpio5_interrupt(int irq, void *dev_id)
{
printk(KERN_INFO "pf5 interrupt received \n");
return IRQ_HANDLED;
}
/**
* gpio5_read - sample the value of the specified GPIO
*/
static ssize_t gpio5_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
{
unsigned int gpio = GPIO_5;
ssize_t ret;
char byte = '0' + gpio_get_value(gpio);
put_user(byte, buf);
return ret;
}
/**
* gpio5_open - claim the specified GPIO
*/
static int gpio5_open(struct inode *ino, struct file *file)
{
unsigned int gpio = GPIO_5;
int ret;
ret = request_irq(INTERRUPT_NUMBER, gpio5_interrupt, IRQF_TRIGGER_FALLING,DRIVER_NAME,NULL);
if (ret)
{
printk(KERN_WARNING "IRQ %d is not free \n", INTERRUPT_NUMBER);
return ret;
}
return 0;
}
/**
* gpio5_close - close the specified GPIO
*
*/
static int gpio5_close(struct inode *ino, struct file *file)
{
unsigned int gpio = GPIO_5;
bfin_gpio_irq_free(gpio);
}
static struct file_operations gpio5_fops = {
.owner = THIS_MODULE,
.read = gpio5_read,
.open = gpio5_open,
.close = gpio5_close,
};
struct platform_driver gpio5_device_driver = {
.driver = {
.name = DRIVER_NAME,
}
};
/**
* gpio5_init - setup our GPIO device driver
*
* Create one GPIO class for the entire driver
*/
static int __init gpio5_init(void)
{
gpio5_class = class_create(THIS_MODULE, DRIVER_NAME);
if (IS_ERR(gpio5_class)) {
pr_init(KERN_ERR PFX "unable to create gpio class\n");
return PTR_ERR(gpio5_class);
}
return platform_driver_register(&gpio5_device_driver);
}
module_init(gpio5_init);
/**
* gpio5_exit - break down our GPIO device driver
*/
static void __exit simple_gpio_exit(void)
{
class_destroy(gpio5_class);
platform_driver_unregister(&gpio5_device_driver);
}
module_exit(gpio5_exit);
MODULE_AUTHOR("bbbb");
MODULE_LICENSE("GPL");
QuoteReplyEditDelete
2010-09-20 00:42:09 Re: GPIO and timers
Mike Frysinger (UNITED STATES)
Message: 93623
as documented, if you only want to do simple "push button" functionality, use the already existing gpio-keys driver
QuoteReplyEditDelete
2010-09-21 03:10:08 Re: GPIO and timers
Shyam sundar (INDIA)
Message: 93645
I went through the routines in gpio_keys.c.
The routine gpio_keys_report_event will be called whenever some state change happens on the pf pin or when the timer expires.I am changing the interrupt mode from IRQF_SAMPLE_RANDOM | IRQF_TRIGGER_RISING |IRQF_TRIGGER_FALLING to IRQF_TRIGGER_FALLING.
I need to set a flag in the gpio_keys_report_event routine and pass this info to the user space.Can i please get some help on how to do this?
QuoteReplyEditDelete
2010-09-21 03:31:26 Re: GPIO and timers
Mike Frysinger (UNITED STATES)
Message: 93692
what exactly do you mean by "set a flag" ? why cant your userspace code simply listen for events from /dev/input/ and respond based on the key pushes ?
QuoteReplyEditDelete
2010-09-22 06:27:42 Re: GPIO and timers
Shyam sundar (INDIA)
Message: 93739
Thanks Mike,I wanted to indicate to the user space application that an interrupt occured using a flag (basically an integer variable).
I didnt knew that I could listen for events from /dev/input !!
Could you please suggest any link so that i understand how this listening works?
QuoteReplyEditDelete
2010-09-22 13:32:55 Re: GPIO and timers
Mike Frysinger (UNITED STATES)
Message: 93762
look in linux-2.6.x/Documentation/input/