timer interrupt problem!
Started by ●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
Reply by ●November 11, 20042004-11-11
-----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 IRQInterruptCause=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}
}