pREG_TIMERn_RUN_CLR and pREG_TIMER0_RUN_CLR difference
Greetings,
defBF609.h has pREG_TIMER0_RUN_CLR address as 0xFFC0140C
and trying to write to it does not yield and results - it doesn't clear TIMER0_RUN
Provided TIMER example has adi_tmr_Close function that makes use of pREG_TIMERn_RUN_CLR (0xFFC0141C)
Note defBF609.h defines it as TIMER0 and adi_tmr_Close makes use of TIMERn definition.
And calling adi_tmr_Close actually works so am I stupid or is there a mistake in defBF609.h
Also I was looking through all documentations for BF609 and couldn't find register address list or at least offset table or what not.. could you point me to it?
Edit Notes
fixed mistakes
[edited by: Edvard at 11:39 AM (GMT 0) on 1 Oct 2019]
bf609
If I step through adi_tmr_Close while debugging it doesn't reset the counter. But if I just run it it does reset. I am confused
The MMR at 0xFFC0141C is:
```#define REG_TIMER0_DATA_IMSK 0xFFC0141C /* TIMER0 Data Interrupt Mask Register */```
As it happens that's the MMR written directly after the assignment to*pREG_TIMERn_RUN_CLR in adi_tmr_close so I suspect that's why it it may appear that *pREG_TIMERn_RUN_CLR in adi_tmr_Close isn't using REG_TIMER0_RUN_CLR when it is.
Are you sure that you are writing the 1 to TIMER0_RUN_CLR at the bit corresponding to the set bit in TIMER0_RUN?
Regards,
Stuart.
Tried writing 2 directly to clear it for TMR1 that would be 0x0002, and tried bit shifting the same way adi_tmr_close does, and I am unable to reset it. I am using ADI_TMR_MODE_SINGLE_PWMOUT Mode and IRQMode ADI_TMR_IRQMODE_DELAY. What I want is to be able to stop timer if action didn't time out (No need for crazy precision here). I can do that when using adi_tmr_Close and then reopening it with adi_tmr_Open (takes more clock cycles adds about micro second in total) but I should be able to do that by disabling Timer. Documentation states that
"It is not necessary to clear the relevant TIMER_RUN bit in order to stop the timer cleanly. At the end of the
pulse, the timer stops automatically and the corresponding TIMER_RUN is cleared. To generate multiple
discrete pulses (as opposed to a continuous PWM waveform), write a 1 to the appropriate TIMER_RUN bit,
wait for the timer to stop, and then write another 1 to the same TIMER_RUN bit."
But it doesn't say that you can't stop it midway by clearing TIMER_RUN. And this is what I am trying to achieve and failing
I've attached a modified version of the timer example from the BF609 BSP. I added code a label "breakHere:" to confirm that the TIMER_RUN bit could be cleared using TIMER0_CLR. While that appears to work, what it also shows is that the timer interrupt remains enabled as the callback is still later run. Does this match what you see?
Regards,
Stuart.
timer_example.zip
I copied the do while loop into my code and stepped after breaking at 'breakHere', while both register and register browser windows don't show that TIMER0_RUN is set to 0x0002, it does pass the 'if' and does seem to clear it as it doesn't enter if after first cycle. The issue is that TIMER0_TMR1_CNT still stays the same (at least if viewed through register and register browser windows).
Also I added some code to log CNT value in this 'do while' loop and let it run without breakpoints.
Code:
fflush(stdout);
freopen("NUL", "a", stdout);
setvbuf(stdout, debugMemory, _IOFBF, 4096);
do {
printf("%d\n",*pREG_TIMER0_TMR1_CNT);
if ((*pREG_TIMER0_RUN & (0x1u << GP_TIMER_NUM)) != 0u) {
*pREG_TIMER0_RUN_CLR = (0x1u << GP_TIMER_NUM);
breakHere: NOP(); /* *** Check that REG_TIMER0_RUN bit has been cleared *** */
}
printf("%d\n",*pREG_TIMER0_TMR1_CNT);
NOP();
} while(gbTimerInt == false);
Note my stdout is pointed to an array in memory to avoid issues caused from printing via debugger.
What I have noticed that if I let it run, CNT keeps on growing as if timer wasn't stopped on the first iteration of the loop. It doesn't get reset either.
I also tried stopping it this way and restarting it and as you can see even if I stop it after 0.22ms and restart it, CNT stays the same and instead of getting 20ms I get 19.76 when it times out by itself
NOTE: If I use adi_tmr_Close to stop it and then reopen handle, then I get 0.22ms before stop and 20ms when I let it timeout by itself. < This is the behavior that I am after but I would like to avoid destruction and creation of timer handle as it seems to takes up additional ~1us and this would be repeated 25*320 times per second adding 8ms worth of delays.
I think the issue is that the TIMER_STOP_CFG default is for graceful rather then immediate stop in PWM timer configuration. The HRM says:
"When a timer’s TIMER_STOP_CFG bit is 0, the timer treats a stop operation as a pending condition. When terminated with this setting, the timer automatically completes the current waveform and then stops cleanly, remaining in a deasserted state. This prevents truncation of the current pulse and unwanted PWM patterns at the TMR pin. The processor can determine when the timer stops running by polling the corresponding TIMER_RUN bit until it reads as read 0 or by waiting for the last interrupt (if enabled)."
So on option is to insert a loop polling TIMER_RUN after disabling the timer. This is achieved using the timer service APIs as follows:
adi_tmr_Enable(ghTimer, false); /* disable timer */
while ((*pREG_TIMER0_RUN & (0x1u << GP_TIMER_NUM)) != 0u); /* wait for graceful stop configuration */
Or you can disable graceful stop then stop the timer immediately, i.e.:
adi_tmr_EnableGracefulStop(ghTimer, false); /* disable graceful stop */
adi_tmr_Enable(ghTimer, false); /* disable timer */
Regards,
Stuart.
Please log in to reply.

