Part Number: SK-AM64
Hi,
I'm trying to configure TIMER_IO4 and TIMER_IO5 on SK-AM64 board. I have configured TIMER PINOUT as follows.
timer4_pins_default: timer4-pins-default { // timer of capture pulse input
pinctrl-single,pins = <
AM64X_IOPAD(0x0258, PIN_INPUT, 4) /* (C17) MCAN1_TX.TIMER_IO4 */
>;
};
timer5_pins_default: timer5-pins-default { // timer for generating pulse output
pinctrl-single,pins = <
AM64X_IOPAD(0x025c, PIN_OUTPUT, 4) /* (D17) MCAN1_RX.TIMER_IO5 */
>;
};
Here is code for pulse input, setting timer for capture mode
static int timer_set_capture(struct dmtimer *timer,
int cap_mode, edg_t edges, int autoreload)
{
struct device *dev;
int rc;
u32 l;
if (unlikely(!timer))
return -EINVAL;
dev = &timer->pdev->dev;
rc = pm_runtime_resume_and_get(dev);
if (rc)
return rc;
l = timer_read(timer, OMAP_TIMER_CTRL_REG);
l &= ~(OMAP_TIMER_CTRL_GPOCFG | OMAP_TIMER_CTRL_CAPTMODE |
OMAP_TIMER_CTRL_TCM_HIGHTOLOW | OMAP_TIMER_CTRL_PT |
OMAP_TIMER_CTRL_TCM_LOWTOHIGH| (0x03 << 10) |
OMAP_TIMER_CTRL_AR | OMAP_TIMER_CTRL_TCM_BOTHEDGES);
/*TIMER IO pin functions as TRIGGER input*/
l |= OMAP_TIMER_CTRL_GPOCFG;
/*Capture on second event: Capture the second enabled capture
event in TIMER_TCAR1 and the second enabled capture event in
TIMER_TCAR2.
*/
if (cap_mode)
l |= OMAP_TIMER_CTRL_CAPTMODE;
switch(edges) {
case NO_CAP:
l &= ~(OMAP_TIMER_CTRL_TCM_HIGHTOLOW |
OMAP_TIMER_CTRL_TCM_LOWTOHIGH |
OMAP_TIMER_CTRL_TCM_BOTHEDGES);
break;
case RISING: l |= OMAP_TIMER_CTRL_TCM_LOWTOHIGH; break;
case FALLING: l |= OMAP_TIMER_CTRL_TCM_HIGHTOLOW; break;
case BOTH: l |= OMAP_TIMER_CTRL_TCM_BOTHEDGES; break;
default : break;
}
if (autoreload)
l |= OMAP_TIMER_CTRL_AR;
timer_write(timer, OMAP_TIMER_CTRL_REG, l);
pm_runtime_put_sync(dev);
return 0;
}
Here is my main timer nodes
&main_timer4 {
status = "okay";
compatible = "elpro,el-pulse-in1";
pintctrl-names = "default";
pintctrl-0 = <&timer4_pins_default>;
};
&main_timer5 {
status = "okay";
compatible = "elpro,el-pulse-ou1";
pintctrl-names = "default";
pintctrl-0 = <&timer5_pins_default>;
};
I can see interrupt happened for timer5 and nothing shows on PIN. when I connect pulse generator to timer4 pin even interrupt didn't happen. Which looks like that pins not been configured properly.
Is there anything else I need to configure to make it work. Both pins asserted (High) all the time. If timer4 pin is configured properly it shouldn't show signal asserted on assigned pin, which is configured as an input.
Here is my C code that I'm using to configure the timer
/*Setup and start timer as an input(capture mode) or output(PWM mode)*/
static int setup_timer(struct dmtimer * timer, bool is_input ) {
unsigned long rate;
if (timer) {
timer_enable(timer);
request_irq(timer->irq, timer_irq_handler, IRQF_TIMER, timer->name, NULL);
if (is_input) {
timer_set_int_enable(timer, OMAP_TIMER_INT_CAPTURE);
timer_set_capture(timer, 1, RISING, 1);
} else {
timer_set_int_enable(timer, OMAP_TIMER_INT_MATCH);
timer_set_pwm(timer, 0, 1, OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE, 1);
timer_set_load(timer, 0);
rate = clk_get_rate(timer->fclk);
timer_set_match(timer, 1, rate*10); //(*: more time; /: less time)fixme make it configurable
}
timer_start(timer);
return 1;
} else
pr_err("Failed to setup the timer\n");
return 0;
}
here is timer_set_pwm function
static int timer_set_pwm(struct dmtimer *timer, int def_on,
int toggle, int trigger, int autoreload)
{
struct device *dev;
int rc;
u32 l;
if (unlikely(!timer))
return -EINVAL;
dev = &timer->pdev->dev;
rc = pm_runtime_resume_and_get(dev);
if (rc)
return rc;
l = timer_read(timer, OMAP_TIMER_CTRL_REG);
l &= ~(OMAP_TIMER_CTRL_GPOCFG | OMAP_TIMER_CTRL_SCPWM | OMAP_TIMER_CTRL_PRE |
OMAP_TIMER_CTRL_PT | (0x03 << 10) | (0x03 << 2)| OMAP_TIMER_CTRL_AR);
if (def_on)
l |= OMAP_TIMER_CTRL_SCPWM;
if (toggle)
l |= OMAP_TIMER_CTRL_PT;
l |= trigger << 10;
if (autoreload)
l |= OMAP_TIMER_CTRL_AR;
// l |= (0x03 << 2); //prescaler
// l |= OMAP_TIMER_CTRL_PRE;
timer_write(timer, OMAP_TIMER_CTRL_REG, l);
pm_runtime_put_sync(dev);
return 0;
}