This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Let me have question about how to use timer interrupt in case of TI AM335X EVM

Hello. I need to use how to use timer interrupt in TI AM335X EVM.

Im gonna call specific function every 2.5ms. But tick timer from kernel doens't provide it.

They are limited timer like 10ms.

While I was looking for solving this problem, i found that dm_timer is included in TI AM 335X.

But there is no manual that explains how to use the api related to dm_timer in TI AM 335X.

So now im begging anyone who can use these api in order for timer.

Help me. Thanks.

Sincerely

  • Hi,

    You can find the dmtimer API inside <linux_dir>/arch/arm/plat-omap/include/plat/dmtimer.h and <linux_dir>/arch/arm/plat-omap/dmtimer.c.

    You can find a simple kernel module code here: http://e2e.ti.com/support/arm/sitara_arm/f/791/p/270632/1091601.aspx#1091601

    Best regards,
    Miroslav

  • HI.

    After i checked your link. i just follow same code like below

    #include <linux/module.h>
    #include <linux/module.h>
    #include <linux/init.h>
    #include <linux/clk.h>
    #include <linux/irq.h>
    #include <linux/interrupt.h>
    #include <asm/io.h>
    #include <linux/types.h>
    #include <plat/dmtimer.h>

    static struct omap_dm_timer *timer_ptr;

    static int32_t timer_irq;

    MODULE_LICENSE("GPL");

    static irqreturn_t timer_irq_handler(int irq, void *dev_id)
    {
        static int32_t irq_counter = 0;

        omap_dm_timer_write_status(timer_ptr, OMAP_TIMER_INT_OVERFLOW);
        omap_dm_timer_read_status(timer_ptr);

        printk("Meow Meow Meow %d\n", irq_counter++);
        
        return IRQ_HANDLED;
    }

    static int __init gptimer_test_init(void)
    {
        int ret = 0;
        struct clk *gt_fclk;
        uint32_t gt_rate;

        printk("gptimer test : starting module omot\n");
        
        timer_ptr = omap_dm_timer_request();
        if(timer_ptr == NULL)
        {
            printk("gptimer test : NO more gp timers available, bailing out\n");
            return -1;
        }
        printk("before1\n");
        omap_dm_timer_set_source(timer_ptr, OMAP_TIMER_SRC_SYS_CLK);
        printk("before2\n");
        omap_dm_timer_set_prescaler(timer_ptr, 0);
        printk("before3\n");
        timer_irq = omap_dm_timer_get_irq(timer_ptr);
        printk("before4\n");
        ret = request_irq(timer_irq, timer_irq_handler, IRQF_DISABLED | IRQF_TIMER, "gptimer test", timer_irq_handler);
        
        if(ret)
        {
            printk("gptimer test : request failed (on irq %d), bailing out\n", timer_irq);
            return ret;    
        }

        printk("before5\n");
        gt_fclk = omap_dm_timer_get_fclk(timer_ptr);    
        printk("after\n");
        gt_rate = clk_get_rate(gt_fclk);
        printk("after2\n");
        
        omap_dm_timer_set_load(timer_ptr, 1, 0xFFFFFFFF - (3 * gt_rate));
        printk("after3\n");
        omap_dm_timer_start(timer_ptr);
        printk("after4\n");
        return 0;
    }

    static void __exit gptimer_test_exit(void)
    {
        printk("gptimer test: cleanup called\n");
        
        omap_dm_timer_stop(timer_ptr);

        free_irq(timer_irq, timer_irq_handler);

        omap_dm_timer_free(timer_ptr);
    }

    module_init(gptimer_test_init);
    module_exit(gptimer_test_exit);

    when i tried "insmod", it has problem.

    error message showed "omap_timer omap_timer.0: omap2_dm_timer_set_src: 518: clk_get() sys_ck FAILED"

    After i was looking for where the problem from, i found the location in kernel.

    it came from "int omap_dm_timer_set_source" function.

    int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
    {
        int ret;
        struct dmtimer_platform_data *pdata;

        if (unlikely(!timer))
            return -EINVAL;

        pdata = timer->pdev->dev.platform_data;
        if (source < 0 || source >= 3)
            return -EINVAL;
        ret = pdata->set_timer_src(timer->pdev, source); // this shows error message when acting.
        return ret;
    }

    because of it, insmod doesn't work. could you help me what's wrong with my code.

    this code is for acting every 3 seconds. actually, i wanna act every 2.5ms.

    it's very difficult as a beginner about this programming. also there is few data that i can learn from.

    thanks for reading my long writings. i look forward to seeing your anwser again. thank you

  • Read the manual!


    Not all timers are able to use OMAP_TIMER_SRC_SYS_CLK.

    Request a specific timer which can switch the clock to OMAP_TIMER_SRC_SYS_CLK.

    Or: omit the setting of the clock source, simly using the default clock.

    May I ask you why you are not using the hrtimer framework of the linux kernel?

  • Hello Wolfgang,

    Can you please explain what is the difference between hrtimer to GP timers ?

    Than you,
    Ran
  • GP timers are hardware timers specific to the AM3xxx.

    "hrtimer" ("high resolution timer") is a linux framework. It is available in every linux kernel.

    You may use hrtimer if all you want is a simple timer.

    You need to use hardware timers if you want to use special hardware features (timer I/O, capture events, etc).

    regards

    Wolfgang