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.

dm timer inaccurate?

Other Parts Discussed in Thread: AM3359

Hi ,

    we are using AM3359 's timer,the prescaler is set to 0, the clk( "clk_rate = clk_get_rate(omap_dm_timer_get_fclk(t_prt_dev->print_timer));" ) is 32000

we set the match value as 0xffffffef(0.5ms) , load value as 0xffffff5f(5ms), but the time seems inaccurate,

we measure the match time is 0.8ms, and  the load time is 8ms, 

why the dm timer inaccurate?

  • Please take a look on "Table 20-1. Timer Resolution and Maximum Range" in the TRM.

    There is no 32kHz clocks. Only 32.768kHz and 25Mhz.

    If DMTimer is using 25Mhz (which should be the default mode I think if you use the function extern void DMTimer3ModuleClkConfig(void); from the evmAM335x.h file).

    Here is what I had written to remember myself:
    /* DMTimer3
     * Frequency of Timer3 clock: 25MHz
     * Counting from TIMER_INITIAL_COUNT to 0xFFFFFFFFu then generate an interrupt
     * Formula to have a timer overflow after T seconds:
     *     TIMER_INITIAL_COUNT = 0xFFFFFFFF - (T * 25000000)
     */

  • HI Paul,

    thanks for your reply,

    1. We got 32KHZ clock through function "clk_rate = clk_get_rate(omap_dm_timer_get_fclk(t_prt_dev->print_timer));". Which is the lib fun. does anyone know why it return 32000?

    2. which BSP you use? we are use psp05.06.00.00, and we can't find DMTimer3ModuleClkConfig(void) and evmAM335x.h

  • Hi,

    Q1: Unfortunately I cannot help you with that one.

    Q2: All right, my bad, I am using the industrial SDK (sys/bios and starterware API). Anyway, even if the frequency was 32768Hz, you should not find 0.8ms and 8ms. I don't know if it's possible with your PSP, but i suggest you to use the 25MHz clock to have more precise timing.

    Regards,
    Paul

  • Hi, 

    thanks for your reply. we are now get a example program from internet. 

    #include <linux/module.h>		
    #include <linux/kernel.h>		
    #include <linux/init.h>			
    #include <linux/clk.h>		
    #include <linux/irq.h>
    #include <linux/interrupt.h>
    #include <asm/io.h>			
    #include <plat/dmtimer.h>
    #include <linux/types.h>
    
    // opaque pointer to timer object
    static struct omap_dm_timer *timer_ptr;
    
    // the IRQ # for our gp timer
    static int32_t timer_irq;
    
    // do some kernel module documentation
    MODULE_AUTHOR("Adam J Kunen <adam@kunen.org>");
    MODULE_DESCRIPTION("OMAP3530 GP Timer Test Module");
    MODULE_LICENSE("GPL");
    
    
    
    /* The interrupt handler.
    This is pretty basic,  we only get an interrupt when the timer overflows,
    We are just going to print a really obnoxious message each time
    */
    static irqreturn_t timer_irq_handler(int irq, void *dev_id)
    {
      // keep track of how many calls we had
      static int32_t irq_counter = 0;
    
    	// reset the timer interrupt status
    	omap_dm_timer_write_status(timer_ptr, OMAP_TIMER_INT_OVERFLOW);
    	omap_dm_timer_read_status(timer_ptr); // YES, you really need to do this 'wasteful' read
    
     // print obnoxious text
      printk("Meow Meow Meow %d\n", irq_counter ++);
    	
    	// tell the kernel it's handled
    	return IRQ_HANDLED;
    }
    
    
    
    // Initialize the kernel module
    static int __init gptimer_test_init(void)
    {
    	int ret = 0;
      struct clk *gt_fclk;
    	uint32_t gt_rate;
    
    
    	printk("gptimer test: starting moudle init\n");
    
      // request a timer (we are asking for ANY open timer, see dmtimer.c for details on how this works)
    	timer_ptr = omap_dm_timer_request();
    	if(timer_ptr == NULL){
    		// oops, no timers available
    		printk("gptimer test: No more gp timers available, bailing out\n");
    		return -1;
    	}
    
       // set the clock source to system clock
    	omap_dm_timer_set_source(timer_ptr, OMAP_TIMER_SRC_SYS_CLK);
    
       // set prescalar to 1:1
    	omap_dm_timer_set_prescaler(timer_ptr, 0);		
    	
      // figure out what IRQ our timer triggers
    	timer_irq = omap_dm_timer_get_irq(timer_ptr);
    
      // install our IRQ handler for our timer
    	ret = request_irq(timer_irq, timer_irq_handler, IRQF_DISABLED | IRQF_TIMER , "gptimer test", timer_irq_handler);
    	if(ret){
    		printk("gptimer test: request_irq failed (on irq %d), bailing out\n", timer_irq);
    		return ret;
    	}
    	
    	// get clock rate in Hz
    	gt_fclk = omap_dm_timer_get_fclk(timer_ptr);
    	gt_rate = clk_get_rate(gt_fclk);
    
    	// set preload, and autoreload
    	// we set it to the clock rate in order to get 1 overflow every 3 seconds
    	omap_dm_timer_set_load(timer_ptr, 1, 0xFFFFFFFF - (3 * gt_rate));
    	
    	// setup timer to trigger our IRQ on the overflow event
    	omap_dm_timer_set_int_enable(timer_ptr, OMAP_TIMER_INT_OVERFLOW);
    	
    	// start the timer!
    	omap_dm_timer_start(timer_ptr);
    
    	// done!		
    	printk("gptimer test: GP Timer initialized and started (%lu Hz, IRQ %d)\n", (long unsigned)gt_rate, timer_irq);
    
    	// return sucsess
    	return 0;
    }
    
    // Cleanup after ourselfs
    static void __exit gptimer_test_exit(void)
    {
    	printk("gptimer test: cleanup called\n");
    
    	// stop the timer
    	omap_dm_timer_stop(timer_ptr);
    		
    	// release the IRQ handler
    	free_irq(timer_irq, timer_irq_handler);
    
      // release the timer
      omap_dm_timer_free(timer_ptr);
    }
    
    // provide the kernel with the entry/exit routines
    module_init(gptimer_test_init);
    module_exit(gptimer_test_exit);
    

    and it output like this:

    1、 why    it print omap_timer omap_timer.0: omap2_dm_timer_set_src: 499: clk_get() sys_ck FAILED? Does linux-3.2.0-psp04.06.00.11 have bugs in timer?

    2、the program is get 1 overflow every 3 seconds, but it seems interrupt every 5 second. What's wrong?

  • Can anybody help us?

  • I can see that your are using omap() functions. It looks weird for me because you are using a sitara processor and not an OMAP one. Are you sure that you got the right Linux SDK ? Are you sure there aren't other functions for Sitara architecture ?

    Sorry I cannot help you more.

    Cheers,
    Paul