2009-04-15 11:49:12 PWM_OUT mode fails with gptimer0 and gptimer1 on BF537E when CONFIG_HZ isn't 100
Jean-Francois Argentino (FRANCE)
Message: 72701
Hello,
I'm using gptimer0 and gptimer1 as internaly generated PPI frame sync in rx mode (negative pulses).
I initialize both timers this way (where pdev->count is the PPI_COUNT register content):
uint16_t cfg = TIMER_MODE_PWM | TIMER_TIN_SEL | TIMER_CLK_SEL;
uint32_t status = get_gptimer_status (0);
if (status & (TIMER_STATUS_TRUN0 | TIMER_STATUS_TRUN1)) {
return -EBUSY;
}
clear_gptimer_pulse_hi (FS1_TIMER_ID);
clear_gptimer_pulse_hi (FS2_TIMER_ID);
set_gptimer_pwidth (FS1_TIMER_ID, pdev->count + 1);
set_gptimer_pwidth (FS2_TIMER_ID, pdev->count + 1);
set_gptimer_config (FS1_TIMER_ID, cfg);
set_gptimer_config (FS2_TIMER_ID, cfg);
This initialization is done only once. Then each time I want to start a PPI transfer, I make:
enable_dma (CH_PPI);
bfin_write_PPI_CONTROL (pdev->control | PORT_EN);
enable_gptimers (FS1_TIMER_BIT | FS2_TIMER_BIT);
And in the DMA interrupt handler:
disable_gptimers (FS1_TIMER_BIT | FS2_TIMER_BIT);
I can't understand why, when configuring the kernel timer frequency for something greater than 100Hz, both timers stop working after some successful transfers. if I'm spying these signals on a scope, they're never rising again, quite shortly...
When CONFIG_HZ=100, they sometimes fail too, but it's really unfrequent, they can work billion times before failing...
Does somebody have an idea of what's could cause this issue?
TranslateQuoteReplyEditDelete
2009-04-16 03:59:15 PWM_OUT mode fails with gptimer0 and gptimer1 on BF537E when CONFIG_HZ isn't 100
Michael Hennerich (GERMANY)
Message: 72730 Stopping Blackfin timers is a bit tricky.
Setting:
disable_gptimers (FS1_TIMER_BIT | FS2_TIMER_BIT);
Will prevent that the timers don't start again. However they are still running until the counter reaches period. So enabling them again during this timeframe will cause unexpected behavior.
What post people do - they let the timers running continuously.
-Michael
QuoteReplyEditDelete
2009-04-16 04:05:42 PWM_OUT mode fails with gptimer0 and gptimer1 on BF537E when CONFIG_HZ isn't 100
Michael Hennerich (GERMANY)
Message: 72731 For more information on this check the Blackfin Hardware Reference
Manual:
"In PWM_OUT mode, a write of a 1 to TIMER_DISABLE does not stop the
corresponding
timer immediately. Rather, the timer continues running and
stops cleanly at the end of the current period (if PERIOD_CNT = 1) or
pulse
(if PERIOD_CNT = 0). If necessary, the processor can force a timer in
PWM_OUT mode to stop immediately by first writing a 1 to the
corresponding
bit in TIMER_DISABLE, and then writing a 1 to the corresponding TRUNx
bit in TIMER_STATUS. See "Stopping the Timer in PWM_OUT Mode" on
page 15-23.
In WDTH_CAP and EXT_CLK modes, a write of a 1 to TIMER_DISABLE stops the
corresponding timer immediately."
QuoteReplyEditDelete
2009-04-16 06:02:50 Re: PWM_OUT mode fails with gptimer0 and gptimer1 on BF537E when CONFIG_HZ isn't 100
Jean-Francois Argentino (FRANCE)
Message: 72741
Michael, thank you for your answer, I'll will try this as soos as possible. But, I hide some details on my way to manage the timers, in fact, I've implemented a workaround for anomaly #05000254 (see tracker #4711), but I'm not sure that Myke Frysinger is agree with my interpretation. So, when I configure the timers (made only once):
uint16_t cfg = TIMER_MODE_PWM | TIMER_TIN_SEL | TIMER_CLK_SEL;
if (ANOMALY_05000254) cfg |= PERIOD_CNT;
clear_gptimer_pulse_hi (FS1_TIMER_ID);
clear_gptimer_pulse_hi (FS2_TIMER_ID);
set_gptimer_pwidth (FS1_TIMER_ID, pdev->count + 1);
set_gptimer_pwidth (FS2_TIMER_ID, pdev->count + 1);
if (ANOMALY_05000254) {
set_gptimer_period (FS1_TIMER_ID, pdev->count + 3);
set_gptimer_period (FS2_TIMER_ID, pdev->count + 3);
}
set_gptimer_config (FS1_TIMER_ID, cfg);
set_gptimer_config (FS2_TIMER_ID, cfg);
When I start a PPI transfer:
enable_gptimers (FS1_TIMER_BIT | FS2_TIMER_BIT);
if (ANOMALY_05000254) stop_gptimers (FS1_TIMER_BIT | FS2_TIMER_BIT);
Where function stop_gptimers is:
void stop_gptimers(uint16_t mask) {
int i;
uint16_t m = mask;
tassert((mask & ~BLACKFIN_GPTIMER_IDMASK) == 0);
for (i = 0; i < BFIN_TIMER_NUM_GROUP; ++i) {
group_regs[i]->disable = m & 0xFF;
m >>= 8;
}
SSYNC();
}
But I've tried without the workaround too, and I've the same problem. More over, the fact that increasing the CONFIG_HZ value greatly increase the failure rate disturb me. As far as I know, I'm the only one to use gptimers through the gptimers.c layer (easy to trace), and the system time uses the core timer, I've "grep" with the gptimer registers names through the kernel sources, but I don't find anything.
2 precisions I've forgot to make: I'm using the SVN version for both kernel and toolchain, on a Bluetechnix CM-BF537E based on DSP rev0.3
TranslateQuoteReplyEditDelete
2009-04-16 06:44:28 Re: PWM_OUT mode fails with gptimer0 and gptimer1 on BF537E when CONFIG_HZ isn't 100
Michael Hennerich (GERMANY)
Message: 72743 >As far as I know, I'm
>the only one to use gptimers through the gptimers.c layer (easy to trace), and the system time uses
>the core timer, I've "grep" with the gptimer registers names through the kernel sources, but I don't
>find anything.
Are you sure?
From top of my head:
linux-2.6.x/drivers/char/bfin_ppi.c
linux-2.6.x/drivers/video/bfin-t350mcqb-fb.c
linux-2.6.x/drivers/video/bfin-lq035q1-fb.c
uclinux-dist-trunk/user/lirc/lirc_bfin_time/lirc_bfin_timer.c
All these for drivers use Mike's gptimers.
Whereas all referenced drivers in linux-2.6.x/drivers use gptimers in PWM_OUT mode.
Please take a look there.
-Michael
QuoteReplyEditDelete
2009-04-16 07:28:25 Re: PWM_OUT mode fails with gptimer0 and gptimer1 on BF537E when CONFIG_HZ isn't 100
Jean-Francois Argentino (FRANCE)
Message: 72747
Sorry, what I mean is that in the system running, I'm the only one to use the gptimers with the PPI driver (not the one of the SVN trunk), I didn't select any video driver in the kernel configuration (but that true if I take a look to the objects file in "drivers/video" I can see "drivers/video/display/built-in.o", "drivers/video/backlight/built-in.o", " drivers/video/built-in.o" and ",drivers/video/fb_notify.o").
More over, I add some "printk" inside the Mike's gptimers, and I just see "my" gptimers registrations (done by the PPI driver). That why I've grep through the kernel sources for the gptimer registers names to see if a driver (or something else like the kernel time keeper) directly use the registers...