Tool/software: Linux
Platform - AM335x Starter Kit
Target - Use an accurate timer with IRQ to toggle GPIO every 100ms.(IRQ shouldn't be delayed more than a period.)
Reference - DMTIMER: e2e.ti.com/.../415079
-------------------------------------------------
Hi,
The question is, I can't request the timer pointer by using
1. omap_dm_timer_request_specific(7) -> ask me to use omap_dm_timer_request_by_cap/node, which I think is because I am using dts(?)
Note. I am using default am335x-evmsk.dts + am33xx.dtsi
2. omap_dm_timer_request_by_cap() -> gets null pointer
I want to request a specific timer and configure it to interrupt every 100ms.
I am totally new to TI platform, please guide me to reach the goal.
Thank you!
Post my work below.
static irqreturn_t timer_irq_handler(int irq, void * dev_id)
{
int status = 0;
/* Read the current Status */
status = omap_dm_timer_read_status(pTimer);
/* Clear the timer interrupt */
if (status == OMAP_TIMER_INT_MATCH)
{
omap_dm_timer_write_status(pTimer, OMAP_TIMER_INT_MATCH);
}
/* Indicate the Interrupt was handled */
return IRQ_HANDLED;
}
static int dmtimer_init(void)
{
int ret = 1;
struct clk *pTimerClk;
/* Need to request Timer 7 */
pTimer = omap_dm_timer_request_specific(7);
if(pTimer == NULL){
/* no timers available */
printk(KERN_INFO "DM timer 7 not available!!\n");
return -1;
}
/* Set the Clock source to the System Clock */
ret = omap_dm_timer_set_source(pTimer, OMAP_TIMER_SRC_SYS_CLK);
/* Determine what IRQ the timer triggers */
timerIrq = omap_dm_timer_get_irq(pTimer);
/* Setup the IRQ handler */
ret = request_irq(timerIrq, timer_irq_handler, IRQF_TIMER, "ext_wdt", NULL);
/* Setup the timer to trigger the IRQ on the match event */
omap_dm_timer_set_int_enable(pTimer, OMAP_TIMER_INT_MATCH);
/* Get the Clock rate in Hz */
pTimerClk = omap_dm_timer_get_fclk(pTimer);
timerRate = clk_get_rate(pTimerClk);
/* Enable the Timer */
/* Needs to be done before we can write to the counter */
omap_dm_timer_enable(pTimer);
/* Set the initial Count */
/* According to section 20.1.3.5 Pulse-Width Modulation, an overflow or match be used to toggle when a compare condition occurs*/
/* Therefore it we will trigger the overflow event almost immediately to ensure our toggle will be generated quickly */
omap_dm_timer_write_counter(pTimer, (0xFFFFFFFF - 5));
/* Setup the Load Register */
/* Setup as autoload to set the the counter back to 0 on an overflow */
omap_dm_timer_set_load(pTimer, 1, 0);
/* Set the the compare register to 100 ms second */
/* This will ensure the signal toggle of 100 ms after the overflow event*/
omap_dm_timer_set_match(pTimer, 1, timerRate/10);
/* Start the timer */
ret = omap_dm_timer_start(pTimer);
printk(KERN_INFO "Timer Start ret %d\n", ret);
/*
* A non 0 returns means the call to init_modules failed; module can't be loaded
*/
return 0;
}
arch_initcall(dmtimer_init)
