[En-Nut-Discussion] AT91SAM7X256 TC1 Timer being disabled

Coleman Brumley cbrumley at gopolar.com
Fri Jul 10 17:48:23 CEST 2009



> -----Original Message-----
> From: Bernd Walter [mailto:nut at cicely.de]
> Sent: Thursday, July 09, 2009 10:05 AM
> To: cbrumley at polarsoft.biz; Ethernut User Chat (English)
> Subject: Re: [En-Nut-Discussion] AT91SAM7X256 TC1 Timer being disabled
> 
> On Wed, Jul 08, 2009 at 04:34:39PM -0400, Coleman Brumley wrote:
> > I then call RegisterTC1Timer(TC1TimerIntr); in some initialization
> code at
> > startup.  This function is pretty simple:
> >
> >
> >
> > static void TC1TimerIntr(void *arg)
> >
> > {
> >
> >        tc1_ticks++;
> >
> >        if(tc1ticks>=5)      //do something every 5ms
> >
> >        {
> >
> >               //do sometthing, set a flag, toggle a PIO pin, etc.
> >
> >               tclticks=0;
> >
> >        }
> >
> > }
> >
> >
> >
> > 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.
> 
> I don't know how ethernuts registration works.
> Normally an ISR must clear the interrupt in the AIC at the end.
> I always handle it myself.
> 
> AT91F_AIC_ConfigureIt(AT91C_ID_UDP, 5,
> AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, (void(*)(void)) ISR_UDP);
> 
> void ISR_UDP( void ) __attribute__ ((naked));
> 
> void
> ISR_UDP( void )
> {
>         IRQ_ENTRY();
>         // TODO
>         IRQ_EXIT();
> }
> 
> 
> 
> AT91F_AIC_ConfigureIt is a macro originating from Atmel:
> 
> #define AT91F_AIC_ConfigureIt( irq_id, priority, src_type, newHandler )
> \
> {
> \
>     unsigned int mask ;
> \
> 
> \
>     mask = 0x1 << irq_id;
> \
>     /* Disable the interrupt on the interrupt controller */
> \
>     AT91C_BASE_AIC->AIC_IDCR = mask ;
> \
>     /* Save the interrupt handler routine pointer and the interrupt
> priority */ \
>     AT91C_BASE_AIC->AIC_SVR[irq_id] = (unsigned int) newHandler ;
> \
>     /* Store the Source Mode Register */
> \
>     AT91C_BASE_AIC->AIC_SMR[irq_id] = src_type | priority  ;
> \
>     /* Clear the interrupt on the interrupt controller */
> \
>     AT91C_BASE_AIC->AIC_ICCR = mask ;
> \
> }

My understanding of the Nut/OS timer implementation is that it does this
already.  Am I missing something?

My ISR shouldn't use NutIrqDisable(&sig_TC1) and then call
NutIrqEnable(&sig_TC1) upon exit should it?  If that were the case, then the
timer interrupt shouldn't work at all...however, in my case it works for
several hours (but never the same amount of several hours) before becoming
disabled.  

Would this have something to do with the use of
NutEnterCritcal/NutExitCritical which is now frowned upon?

- Coleman



More information about the En-Nut-Discussion mailing list