kann someone help to Programm hadware timer with kernel 4.19 for am335xx target. I found some example here, by this is for old Linux kernel.
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.
kann someone help to Programm hadware timer with kernel 4.19 for am335xx target. I found some example here, by this is for old Linux kernel.
#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 </opt/work/trunk/BSP/AM335X/Linux/linux-3.14.26-g2489c02/arch/arm/plat-omap/include/plat/counter-32k.h>
#include </opt/work/trunk/BSP/AM335X/Linux/linux-3.14.26-g2489c02/arch/arm/plat-omap/include/plat/dmtimer.h>
#include <linux/gpio.h>
#define DRIVER_NAME "test_dev"
#define TIMER_MAX 0xFFFFFFFF
static struct omap_dm_timer *timer_ptr = NULL;
static struct omap_dm_timer *timer_ptr1 = NULL;
static int32_t timer_irq;
static int32_t timer_irq1;
static uint32_t timer_rate;
u32 irq_count =0;
static irqreturn_t timer_irq_handler( int irq, void * dev_id)
{
unsigned int retval;
retval = omap_dm_timer_read_status(timer_ptr);
if (!retval)
return IRQ_NONE;
if (retval & ~OMAP_TIMER_INT_MATCH)
printk("Unexpected interrupt source: %x\n", retval);
omap_dm_timer_write_status(timer_ptr,
OMAP_TIMER_INT_MATCH |
OMAP_TIMER_INT_OVERFLOW |
OMAP_TIMER_INT_CAPTURE);
omap_dm_timer_read_status(timer_ptr);
irq_count++;
omap_dm_timer_start(timer_ptr1);
if(irq_count > 100)
{
omap_dm_timer_stop(timer_ptr);
omap_dm_timer_stop(timer_ptr1);
printk("________________DM Timer Count %d\n", irq_count );
irq_count =0;
}
return IRQ_HANDLED;
}
static irqreturn_t timer_irq_handler1( int irq, void * dev_id)
{
unsigned int retval;
retval = omap_dm_timer_read_status(timer_ptr1);
if (!retval)
return IRQ_NONE;
if (retval & ~OMAP_TIMER_INT_MATCH)
printk("Unexpected interrupt source: %x\n", retval);
omap_dm_timer_write_status(timer_ptr1,
OMAP_TIMER_INT_MATCH |
OMAP_TIMER_INT_OVERFLOW |
OMAP_TIMER_INT_CAPTURE);
omap_dm_timer_read_status(timer_ptr1);
omap_dm_timer_stop(timer_ptr1);
return IRQ_HANDLED;
}
static int init_timing(struct omap_dm_timer *timer,unsigned int on_time,unsigned int off_time)
{
u32 load, match;
load = timer_rate * (on_time + off_time) / 1000;
match = timer_rate * on_time / 1000;
omap_dm_timer_set_load(timer, 1, -load);
omap_dm_timer_set_match(timer, 1, -match);
omap_dm_timer_write_counter(timer, - 2);
omap_dm_timer_set_pwm(timer, 1, 1, OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE);
omap_dm_timer_set_int_enable(timer, OMAP_TIMER_INT_MATCH);
return 0;
}
static int test_module_init(struct platform_device *pdev)
{
int ret = 1,i;
struct clk *timer_clk;
struct device_node *timer_device_node;
struct device_node *timer_device_node1;
printk(KERN_INFO " INIT DM Timer\n");
timer_device_node = of_parse_phandle(pdev->dev.of_node, "DMtimer", 0);
timer_ptr = omap_dm_timer_request_by_node(timer_device_node);
if(timer_ptr == NULL)
{
/* no timers available */
printk(KERN_INFO "Can't request specified DM Timer 4\n");
return -1;
}
timer_device_node1 = of_parse_phandle(pdev->dev.of_node, "DMtimer1", 0);
timer_ptr1 = omap_dm_timer_request_by_node(timer_device_node1);
if(timer_ptr1 == NULL)
{
/* no timers available */
printk(KERN_INFO "Can't request specified DM Timer 7\n");
return -1;
}
/* Set the Clock source to the System Clock */
ret = omap_dm_timer_set_source(timer_ptr, OMAP_TIMER_SRC_SYS_CLK);
ret = omap_dm_timer_set_source(timer_ptr1, OMAP_TIMER_SRC_SYS_CLK);
// set prescalar to 1:1
//omap_dm_timer_set_prescaler(timer_ptr, 0);
omap_dm_timer_enable(timer_ptr);
omap_dm_timer_enable(timer_ptr1);
/* Determine what IRQ the timer triggers */
timer_irq = omap_dm_timer_get_irq(timer_ptr);
timer_irq1 = omap_dm_timer_get_irq(timer_ptr1);
/* Setup the IRQ handler */
ret = request_irq(timer_irq, timer_irq_handler, IRQF_TIMER, "DMTimer 4", NULL);
/* Setup the IRQ handler */
ret = request_irq(timer_irq1, timer_irq_handler1, IRQF_TIMER, "DMTimer 7", NULL);
/* Get the Clock rate in Hz */
timer_clk = omap_dm_timer_get_fclk(timer_ptr);
timer_rate = clk_get_rate(timer_clk)/1000;
init_timing(timer_ptr,180,5); //180 microsec
init_timing(timer_ptr1,100,5); // 100 microsec
/* Start the timer */
omap_dm_timer_start(timer_ptr);
//omap_dm_timer_start(timer_ptr1);
return 0;
}
static int test_module_exit(struct platform_device *pdev)
{
int ret = 1;
/* stop the timer */
ret = omap_dm_timer_stop(timer_ptr);
printk(KERN_INFO "Timer Stop ret = %d\n", ret);
ret = omap_dm_timer_stop(timer_ptr1);
printk(KERN_INFO "Timer Stop ret = %d\n", ret);
/* Release the IRQ handler */
free_irq(timer_irq, NULL);
free_irq(timer_irq1, NULL);
printk(KERN_INFO "Free IRQ Done\n");
/* Release the timer */
ret = omap_dm_timer_free(timer_ptr);
printk(KERN_INFO "Timer Free ret = %d\n", ret);
ret = omap_dm_timer_free(timer_ptr1);
printk(KERN_INFO "Timer Free ret = %d\n", ret);
return 0;
}
static const struct of_device_id test_module_timer_of_match[] = {
{ .compatible ="ti,am335x-timer" },
{},
};
static struct platform_driver test_module_timer_driver = {
.driver = {
.name = DRIVER_NAME,
.of_match_table = test_module_timer_of_match,
},
.probe = test_module_init,
.remove = test_module_exit,
};
module_platform_driver(test_module_timer_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Sahaya Darcius");
MODULE_DESCRIPTION("Sample DMTimer Test Driver");
MODULE_VERSION("0.1");
I use this example, but it's not work. I have this error :
Can't request specified DM Timer 4
Hello Neguimeya,
You posted a custom kernel driver. Note that the .probe function is set to test_module_init. That means that during bootup, when Linux is reading through the device tree and finds a node with compatible = ti,am335x-timer, then it will go to this driver and run function test_module_init. Note that in Linux Processor SDK 6.3, driver timer-ti-dm.c also lists compatible = "ti,am335x-timer'. I am not sure what happens when two different drivers list the same compatible string.
1) Are you trying to create a custom kernel driver, or just access a timer from user space?
2) What are you trying to do with the timer?
Regards,
Nick
Hello Nick,
I have to programm a custom kernel driver. I will be use it to generated 400 nicrosecond PWM and I want to use timer dmtimer nummer 4. I have also change the name of timer for to compatible = "ti,am335x-timer-hadware" , but this does'nt work.