mega16 int1 cant fire in a tight loop!

Go To Last Post
6 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have a mega16 running at 14.7456MHz. Have a 10khz about sq wave banging on int1, armed for rising edge. The int handler just increments an 8 bit global counter (so its volatile). The main prog has a line like

while(intcount < 16){};

which compiles to 3 instructions: load, compare immediate, branch back 3 inst. My hypothesis is this 3 inst loop is too tight to allow the int to hit. When I put something in the empty brackets, it magically starts working.

So can someone confirm this behavior in any other mega16, or mrga128 perhaps?

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Bob,

Well, it worked ok for me-
A mega16L at 14.7 mhz responded to interrupts on int1 up to 400 khz.

Here is the code:

#include 
#include 
#include 
#include 

SIGNAL (SIG_INTERRUPT1)
{
    static uint8_t poo=0;
    poo++;
    PORTA=poo;
}

int main (void)
{
    DDRA  = 0xff;
    PORTA = 0x00;
    DDRD  = 0x00;
    PORTD = 0xff;
    MCUCR = 0x0c;           // rising edge trigger on int1
    GICR  = 0x80;           // enable int1
    sei();
    uint8_t intcount=0; 
    while(intcount < 16);
    return 1;
}

Tom Pappano
Tulsa, Oklahoma

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ooops,

I forgot to sign that,

Tom Pappano
Tulsa, Oklahoma

ps:

FWIW the chip is a Mega16L8PI with a 0308 date code

Tom Pappano
Tulsa, Oklahoma

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've never had a problem with interrupts executive from a tight control loop. The interrupt request is latched in hardware and will be serviced as soon as the current instruction has completed execution. If multiple interrupt requests are present, they will be serviced in order of priority.

Even the code "while(1);" will allow interrupt service without problems.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Earlier devices (circa 163/603/103) had problems regarding interrupts and tight loops with 2-word instructions.

AFAIK this was resolved in newer devices.

The m163errata sheet says..

Quote:

Increased Interrupt Latency
In this device, some instructions are not interruptable, and will cause the interrupt latency to increase. The only practical problem concerns a loop followed by a two-word instruction while waiting for an interrupt. The loop may consist of a branch instruction or an absolute or relative jump back to itself like this:

loop: rjmp loop

In this case, a dead-lock situation arises.
Problem Fix/Workaround
In assembly, insert a nop instruction immediately after a loop to itself. The problem will normally be detected during development. In C, the only construct that will give this problem is an empty "for" loop; "for(;;)". Use "while(1)" or "do{} while(1)" to avoid the problem.

.. while the m103 errata sheet goes into more detail:

Quote:
Skip Instruction with Interrupts
A skip instruction (SBRS, SBRC, SBIS, SBIC, CPSE) that skips a two-word instruction needs three clock cycles. If an interrupt occurs during the first or second clock cycle of this skip instruction, the return address will not be stored correctly on the stack. In this situation, the address of the second word in the two-word instruction is stored. This means that on return from interrupt, the second word of the two-word command will be decoded and executed as an instruction. The ATmega103L has four two-word instructions: LDS, STS, JMP and CALL.
Notes: 1. This can only occur if all of the following conditions are true:
- A skip instruction is followed by a two-word instruction.
- The skip instruction is actually skipping the two-word instruction.
- Interrupts are enabled, and at least one interrupt source can generate an interrupt.
- An interrupt arrives in the first or second cycle of the skip instruction.
2. This will only cause problems if the address of the following LDS or STS command points to an address beyond 400 Hex.
Problem Fix/Workaround
For C-programs, use the IAR compiler version 1.40b or later. The compiler will never generate the sequence. For assembly program, avoid skipping a two-word instruction if interrupts are enabled.

But like I said, this problem should have been resolved in the mega16.

Edit: On further reading of those errata, they are two different problems. Both however, are related to interrupts and 2-word instructions. Yet again, none of that should apply to the mega16.

/* John Butera */

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Very interesting.... Thanks for testing!...... I worked on this for quite a while.... was very surprised to see it 'magically' start working after sticking some counter in the empty braces......

Imagecraft compiler user