EmbeddedRelated.com
Forums
Memfault Beyond the Launch

timer interrupt problem!

Started by shishir_v_joshi November 10, 2004

Hi,
I was trying to use the timer interrupt on the prototype development
board on RCM3000. I found that my code is resetting again and again.
The code snippet is as follows:
#nodebug
#define FAST_INTERRUPT 0
interrupt_vector timera_intvec timer_isr
main()
{
WrPortI(PGFR,&PGFRShadow,0);
WrPortI(PGCR,&PGCRShadow,0);
WrPortI(PGDR,&PGDRShadow,0xFF);
WrPortI(PGDDR,&PGDDRShadow,0xFF);

//timer
WrPortI(TACR,&TACRShadow,0x01);
WrPortI(TAPR,&TAPRShadow,0x01);
WrPortI(TACSR,&TACSRShadow,0x03);
WrPortI(TAT1R,&TAT1RShadow,0xFF);

while(1);
}

nodebug root interrupt void timer_isr()
{
WrPortI(PGDR,&PGDRShadow,0x00);
WrPortI(TAT1R,&TAT1RShadow,0xFF);
}

Is there anything wrong in this piece of code? All the ISR is doing is
setting the LED on the prototype board.

Thanks in advance
-SVJ



 
-----Original Message-----
From: shishir_v_joshi [mailto:s...@yahoo.com]
Sent: Wednesday, November 10, 2004 5:13 PM
To: r...@yahoogroups.com
Subject: [rabbit-semi] timer interrupt problem!


Hi,
  I was trying to use the timer interrupt on the prototype development
board on RCM3000. I found that my code is resetting again and again.
The code snippet is as follows:
#nodebug
#define FAST_INTERRUPT 0
interrupt_vector timera_intvec timer_isr
main()
{
      WrPortI(PGFR,&PGFRShadow,0);
   WrPortI(PGCR,&PGCRShadow,0);
   WrPortI(PGDR,&PGDRShadow,0xFF);
   WrPortI(PGDDR,&PGDDRShadow,0xFF);

   //timer
   WrPortI(TACR,&TACRShadow,0x01);
   WrPortI(TAPR,&TAPRShadow,0x01);
   WrPortI(TACSR,&TACSRShadow,0x03);
   WrPortI(TAT1R,&TAT1RShadow,0xFF);

   while(1);
}

nodebug root interrupt void timer_isr()
{
      WrPortI(PGDR,&PGDRShadow,0x00);
      WrPortI(TAT1R,&TAT1RShadow,0xFF);
}

Is there anything wrong in this piece of code? All the ISR is doing is
setting the LED on the prototype board.

Thanks in advance
-SVJ[Robert] There are a number of problems.  First, timer A1 is not recommended for C--assembly only because you only have 512 clocks within which it may work, and a good portion of those are spent pushing and popping the complete register set.  Timer A1 IRQ's should be in strict assembly and should not push very much on the stack; push af, hl, and possibly de.
 
The second problem is that you must clear the source of the interrupt; the Rabbit won't do that for you when the interrupt is entered.  A read of TACSR will clear the interrupt.
 
Here is your modified code--
interrupt_vector timera_intvec timer_isr
main()
{
      WrPortI(PGFR,&PGFRShadow,0);
   WrPortI(PGCR,&PGCRShadow,0);
   WrPortI(PGDR,&PGDRShadow,0xFF);
   WrPortI(PGDDR,&PGDDRShadow,0xFF);

   //timer
   WrPortI(TACR,&TACRShadow,0x81);    // <--Modified to allow A7 to be clocked off A1
   WrPortI(TAPR,&TAPRShadow,0x01);
   WrPortI(TACSR,&TACSRShadow,0x81);  // <--Modified to only get an IRQ from timer A7 instead of A1
   WrPortI(TAT1R,&TAT1RShadow,0xFF);  
   WrPortI(TAT7R, &TAT7RShadow, Divisor); // <--On most boards (22Mhz), this is the number of 1/43200'ths of a second you want between IRQ's

   while(1);
}

nodebug root interrupt void timer_isr()
{   auto int InterruptCause;    // Integers produce better code than char's in an IRQ
    InterruptCause=RdPortI(TACSR); // This line is a necessity; without it, the IRQ will be re-entered the moment the function exits.
    if (InterruptCause & 0x80) { // Check the cause of the IRQ
      WrPortI(PGDR,&PGDRShadow,0x00);
      // WrPortI(TAT1R,&TAT1RShadow,0xFF);  // Only on timer B do you rewrite these registers
    }
}
 
 




Memfault Beyond the Launch