2010-09-13 06:35:02     GPIO and timers

Document created by Aaronwu Employee on Aug 23, 2013
Version 1Show Document
  • View in full screen mode

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/

Attachments

    Outcomes