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.

AM335x DM Timer Latency

Hello,

   I am using AM335xevm with sdk 8. 

I am using one of the DM timer to generate signal for a specific time (around 200 microseconds).  I am succeeded to generate the signal, however when i use the logical analyzer to verify the signal time, i found that, there is a random delay (about 60 microseconds) occurs.  

Please find the attached source code.

#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 <linux/types.h>			
#include <linux/platform_device.h>
#include <linux/platform_data/dmtimer-omap.h>
#include <linux/sched_clock.h>
#include "../../arch/arm/plat-omap/include/plat/dmtimer.h"
#include <linux/gpio.h>
#include <linux/cdev.h> 
// do some kernel module documentation

MODULE_DESCRIPTION("External Interrupt Test Module");
MODULE_LICENSE("GPL");

static struct {
	struct omap_dm_timer *timer_ptr;
	int freq;
	unsigned long match;
	unsigned long timer_rate;
	int duty_cycle;
	
} SGTDev;

static int32_t timer_irq;


#define GPIO_TO_PIN(bank, gpio) ((32 * (bank)) + (gpio)) 
#define IRQ_GPIO_PIN                GPIO_TO_PIN(3, 7)
#define MOT_STEP_PIN            GPIO_TO_PIN(1, 26)	//T16

#define TIMER_MAX_VALUE 0xffffffff
int irq_counter=0;

struct sgt_dev  
{  
    struct cdev cdev;  
    dev_t devno;
    struct class *sgt_dev_class; 
   // struct fasync_struct *async_queue;
 
    int message_cdev_open;
    
    int irq_no; 
    unsigned int triggered_flags;
    
};

struct sgt_dev sgt_dev;

int TIMER_SPEED_TABLE[6]={1,4,8,12,16,20};


static irqreturn_t timer_irq_handler(int irq, void *dev_id)
{
	// keep track of how many calls we had
	
	int timer_speed; 
	int status = 0;
	
	
	timer_speed=SGTDev.timer_rate;
	irq_counter ++;
	 /* Read the current Status */
	status = omap_dm_timer_read_status(SGTDev.timer_ptr);
	//printk(KERN_INFO "status %x  OMAP_TIMER_INT_MATCH = %x timer_speed = %ld\n",status,OMAP_TIMER_INT_MATCH,timer_speed);
	/* Clear the timer interrupt */
	if (status == OMAP_TIMER_INT_MATCH)
	{
		//omap_dm_timer_write_status(SGTDev.timer_ptr,  OMAP_TIMER_INT_MATCH);
		omap_dm_timer_write_status(SGTDev.timer_ptr,
				OMAP_TIMER_INT_MATCH	|
				OMAP_TIMER_INT_OVERFLOW	|
				OMAP_TIMER_INT_CAPTURE);
		omap_dm_timer_read_status(SGTDev.timer_ptr);
	} 
	  
	gpio_set_value(MOT_STEP_PIN,1);
	udelay(10);
	gpio_set_value(MOT_STEP_PIN,0);
	omap_dm_timer_set_match(SGTDev.timer_ptr, 1, timer_speed);
	// tell the kernel it's handled
	if(irq_counter>1000)
	{
		omap_dm_timer_set_int_disable(SGTDev.timer_ptr,  OMAP_TIMER_INT_MATCH);	/* stop timer */
		printk("________________DM Timer Count  %d\n", irq_counter ++);
	}
	return IRQ_HANDLED;
}


// Initialize the kernel module
static int __init gptimer_test_init(void)
{
	struct sgt_dev * dev = &sgt_dev;  
	int ret = 0;
	 struct clk *gt_fclk;
	uint32_t gt_rate ;
	const char* gpio_lable = "sg_msg_gpio";
	
	dev->triggered_flags = 0;
	dev->irq_no = 0;

	printk("gptimer test: starting moudle init\n");
	///////////////////////////////////////////////////////////////////////////////////////////////
	//			Initializing the DM Timer 1					///
	///////////////////////////////////////////////////////////////////////////////////////////////
  	//SGTDev.timer_ptr = omap_dm_timer_request();
  	SGTDev.timer_ptr = omap_dm_timer_request_by_cap(OMAP_TIMER_HAS_PWM);  
	if(SGTDev.timer_ptr == NULL){
		// oops, no timers available
		printk("gptimer test: No more gp timers available, bailing out\n");
		return -1;
	}

   	omap_dm_timer_set_source(SGTDev.timer_ptr, OMAP_TIMER_SRC_SYS_CLK);/*set the clock source to system clock*/
	omap_dm_timer_set_prescaler(SGTDev.timer_ptr, 0);	/*set prescalar to 1:1*/
	timer_irq = omap_dm_timer_get_irq(SGTDev.timer_ptr);	/*figure out what IRQ our timer triggers*/

	ret = request_irq(timer_irq, timer_irq_handler, IRQF_DISABLED | IRQF_TIMER , "gptimer test", timer_irq_handler);	/*install our IRQ handler for our timer*/
	if(ret){
		printk("gptimer test: request_irq failed (on irq %d), bailing out\n", timer_irq);
		return ret;
	}
	
	gt_fclk = omap_dm_timer_get_fclk(SGTDev.timer_ptr);	/*get clock rate in Hz*/
	gt_rate = clk_get_rate(gt_fclk)/10000;
	SGTDev.timer_rate = gt_rate ;
	omap_dm_timer_enable(SGTDev.timer_ptr);
	omap_dm_timer_write_counter(SGTDev.timer_ptr, 0);
	omap_dm_timer_set_match(SGTDev.timer_ptr, 1, gt_rate);
	omap_dm_timer_set_pwm(SGTDev.timer_ptr, 0, 1, OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE);
	omap_dm_timer_set_int_enable(SGTDev.timer_ptr, OMAP_TIMER_INT_MATCH);	
										
	
	printk("gptimer test: GP Timer1  initialized and started (%lu Hz, IRQ %d)\n", (long unsigned)gt_rate, timer_irq);
	
	///////////////////////////////////////////////////////////////////////////////////////////////
	//	Initializing the GPIO								///
	///////////////////////////////////////////////////////////////////////////////////////////////
	printk("SG_MOT_DEV: Initializing the GPIO\n");
	
	/*MOT_STEP_PIN */
	ret = gpio_request(MOT_STEP_PIN, gpio_lable);
	if(ret){
		printk(KERN_ERR "SG_MOT_DEV: MOT_STEP_PIN_request() failed !\n");
		return ret;
	}
	ret = gpio_direction_output(MOT_STEP_PIN,0);
	if(ret){
		printk(KERN_ERR "SG_MOT_DEV: gpio_direction_output() failed !\n");
		return ret;
	}
	
	
	printk("GPIO: Initial Success\n");

	/*start the timer!*/	
    	ret = omap_dm_timer_start(SGTDev.timer_ptr);
    	printk(KERN_INFO "Timer Start ret %d\n", ret);
	
	return 0;
}

// Cleanup after ourselfs
static void __exit gptimer_test_exit(void)
{
	struct sgt_dev *dev = &sgt_dev;  
	
	printk("gptimer test: cleanup called\n");

	// stop the timer
	omap_dm_timer_stop(SGTDev.timer_ptr);
			
	// release the IRQ handler
	free_irq(timer_irq, timer_irq_handler);
	
	// release the timer
	omap_dm_timer_free(SGTDev.timer_ptr);
	
	// gpio free
   	gpio_free(MOT_STEP_PIN);  
	
	
}

// provide the kernel with the entry/exit routines
module_init(gptimer_test_init);
module_exit(gptimer_test_exit);

Here is my Logical analyzer result,

Please guide me to generate signal with specific time using DM timer without any latency.

Thank you,

With Regards,

Sahaya P