« Return to Thread: AT91SAM7X256 TC1 Timer being disabled

Re: AT91SAM7X256 TC1 Timer being disabled

by Coleman Brumley-3 :: Rate this Message:

Reply to Author | View in Thread

Tim,

Thank you.  I'm testing this code now in my application...so far so good.  

The last test took almost 12 hours to fail though, so I won't know for sure
until tomorrow.

- Coleman


> -----Original Message-----
> From: en-nut-discussion-bounces@... [mailto:en-nut-discussion-
> bounces@...] On Behalf Of Timothy M. De Baillie
> Sent: Friday, July 10, 2009 12:13 PM
> To: Ethernut User Chat (English)
> Subject: Re: [En-Nut-Discussion] AT91SAM7X256 TC1 Timer being disabled
>
> Coleman Brumley wrote:
> > What I'm finding, though, is that after some amount of time (several
> hours,
> > for instance) the TC1 interrupt is being disabled.  If I toggle a PIO
> pin in
> > TC1TimerIntr and the app gets in this state, then the PIO pin is not
> longer
> > being toggled.   I can find no reference to NutIrqDisable for sig_TC1
> in the
> > code though.
> >
> >
> >
> > Has anyone else come across this type of scenario?  I'm using Nut/OS
> v4.6.4.
> >
> This is a problem we have seen on many occasions.  The problem lies in
> that Ethernut does not allow re-entrance of IRQs.  If you are to get
> two
> interrupts on your timer before you are able to handle them, then it
> causes the timer to just stop.
>
> The REAL solution is to rewrite the IRQ_ENTRY and IRQ_EXIT to allow for
> re-entrance of IRQs (and not disable IRQs).
>
> Our temporary solution involves using a wrapping timer instead of a
> resetting timer.  Additionally, if the timer's accuracy is highly
> important, you should check for overflow and handle it (ie: two
> interrupts before handler, should be detectable by amount in TC1_CV)
>
> // CODE
>
> #define COMPARE_ADDER 0xdc8
> signed short compare_value = COMPARE_ADDER;
>
> static void RealTimeClock(void *arg){
>
>    local_clock++;
>
>    //you could check for overflow here
>
>    //increase compare value to next interrupt value
>    //(signed short allows for overflow wrapping)
>    compare_value += COMPARE_ADDER;
>    outr(TC1_RC, compare_value);
>
> }
>
> void InitTimer1(void){
>
>    //change the AIC to allow handle of TC1 interrupt
>    outr(AIC_IECR, _BV(TC1_ID));
>
>    //enable timer1 clock
>    outr(PMC_PCER, _BV(TC1_ID));
>
>    //disable the timer
>    outr(TC1_CCR, TC_CLKDIS);
>
>    //disable interrupts on the timer
>    outr(TC1_IDR, 0xFFFFFFFF);
>
>    //reading the status register will clear any pending interrupt
>    inr(TC1_SR);
>
>    //Select MCK/32, inc on + edge (45.1584MHz/32 = 1.4112MHz)
>    outr(TC1_CMR, TC_CLKS_MCK32);
>
>    //set compare value to 2.50ms (.0025 * 1411200) = 3528 (0xdc8)
>    outr(TC1_RC, COMPARE_ADDER);
>
>    //enable the timer
>    outr(TC1_CCR, TC_CLKEN);
>
>    //enable the rc compare interrupts
>    outr(TC1_IER, TC_CPCS);
>
>    //register the interrupt
>    NutRegisterIrqHandler(&sig_TC1, RealTimeClock, 0);
>
>    //set to highest priority (7)
>    NutIrqSetPriority(&sig_TC1, 7);
>
>    //enable the interrupt
>    NutIrqEnable(&sig_TC1);
>
>    //reset the counter and start the clock
>    outr(TC1_CCR, TC_SWTRG);
>
> }
>
> //END CODE
>
> Hope this helps,
>
> Tim DeBaillie
> _______________________________________________
> http://lists.egnite.de/mailman/listinfo/en-nut-discussion

_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

 « Return to Thread: AT91SAM7X256 TC1 Timer being disabled