Page 1 of 1
5213 DMA Timer Question
Posted: Thu Aug 23, 2018 5:20 pm
by joepasquariello
Hello,
We are using a DMA timer configured for input capture on rising edges to measure the period of a low-frequency signal (0-100 Hz). The signal source is a proximity sensor, whose output is converted to fiber. Our board has a fiber receiver with slow rise/fall times. Rise times are 50-60 ns and fall times 30-40 ns. We're getting weird traps when we measure the signal via fiber, but no problem at all if we measure clean PWM output by another DMA timer and connected directly to the MOD5213 pin. Is our fiber receiver "too slow" to connect directly to a DMA timer? Could we be getting spurious interrupts?
I can't find anything about input capture signal specifications in the Freescale/NXP docs, but I have a vague memory of someone telling me to "be careful" with the DMA timers.
Thanks,
Joe
Re: 5213 DMA Timer Question
Posted: Sat Aug 25, 2018 5:04 am
by pbreed
Are you turning the timer interrupt on and off? or just leaving it on?
Turning interrupts on/off can some times generate spurious interrupts...
You may be detecting multiple edges with the slow rise times...
Just leave the interrupt on and process them....
If you have to turn them off do so with the timer resigsters, not the interrupt controller....
Re: 5213 DMA Timer Question
Posted: Sat Aug 25, 2018 7:22 am
by joepasquariello
Hi Paul,
Thanks for your reply. No, I'm not turning interrupts on and off. Interrupts occur on rising edges, and the ISR is as short as I can make it. It just clears the CAP interrupt flag, reads the capture register, computes period, and posts the period value to an OS_Q. The values in the OS_Q are processed at task level. So you do think it's possible that a rise time of 50-60 ns could trigger multiple interrupts? If you were doing this measurement, would you put more digital logic between the fiber receiver and the DMA timer so that rise times seen at the MOD5213 pin would be faster?
Is the DMA timer's response a function of the clock frequency? I'm using fsys/1 now. If I used fsys/16, does that affect the edge detection, or just the resolution of the measurement? Seems like the timer resolution should not limit or control the edge detection.
Joe
Re: 5213 DMA Timer Question
Posted: Mon Aug 27, 2018 6:06 am
by pbreed
Are you using the INTERRUPT macro to set up your ISR?
Can you post your ISR and ISR setup code?
Re: 5213 DMA Timer Question
Posted: Tue Aug 28, 2018 10:34 am
by joepasquariello
Yes, I'm using INTERRUPT. Here is the call to SetIntc(), the ISR, and a function to configure the DMA timer for IC.
SetIntc( (long)&dtim0_isr, 19+0, 6, 4+0 ); // vector=19, level=6, pri=4
/******************************************************************************
* INTERRUPT - DMA Timer 0 Input Capture
******************************************************************************/
INTERRUPT( dtim0_isr, 0x2600 )
{
static ulong cap=0,prev=0,period=0; // static capture values
sim.timer[x].dter = MCF_DTIM_DTER_CAP; // clear CAP interrupt
cap = sim.timer[0].dtcr; // read capture register
period = cap - prev; // compute period
prev = cap; // save capture for next time
OSQPost( &q_hubTachA, (void*)period ); // post period to Q
}
/******************************************************************************
* DTIMxInputCapture configures DMA timer for input capture with interrupt
******************************************************************************/
void DTIMxInputCapture( short x, BYTE ps, BYTE capture_edge )
{
sim.timer[x].tmr = 0; // disable BEFORE setting regs
sim.timer[x].tmr = MCF_DTIM_DTMR_PS(ps) // divide by ps+1 (1-256)
| MCF_DTIM_DTMR_CLK_DIV1; // clk = Fsys/1
switch (capture_edge) { // set CE = 00,01,10,11
default:
case 0: sim.timer[x].tmr |= MCF_DTIM_DTMR_CE_NONE; break;
case 1: sim.timer[x].tmr |= MCF_DTIM_DTMR_CE_RISE; break;
case 2: sim.timer[x].tmr |= MCF_DTIM_DTMR_CE_FALL; break;
case 3: sim.timer[x].tmr |= MCF_DTIM_DTMR_CE_ANY; break;
}
sim.timer[x].txmr = 0; // DMAEN=0, MODE16=0
sim.timer[x].ter = MCF_DTIM_DTER_REF // REF=1 (clear OC interrupt)
| MCF_DTIM_DTER_CAP; // CAP=1 (clear IC interrupt)
sim.timer[x].tcn = 0x0000; // write ANY value to clear tmr
sim.timer[x].tmr |= MCF_DTIM_DTMR_RST; // RST=1 (enable timer)
}