Voting resources, early voting, and poll worker information - VOTE. ... Adafruit is open and shipping.
0

attiny2313 - infinite reset loop
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

attiny2313 - infinite reset loop

by sheu on Thu Aug 19, 2010 5:07 am

This is not a particulary attiny2313-specific problem (I think...). Background: I'm working on interfacing an attiny2313 to an SD card, amongst other things. Surprisingly, I've already got that part (the complicated SD card interfacing over SPI part) working, since it involves no interrupts. But when I enable the timer interrupt, then this infinite reset loop madness occurs. Hence I've trimmed down the problem case into a simple program that just blinks an LED on PA1.

Basically, whenever I enable the timer/counter1 overflow interrupt vector, the chip seems to reset itself when the interrupt hits. As this example program goes, what the chip should do is to blink the LED once, then busy-wait forever. Instead, the chip blinks the LED continuously as it is somehow being reset when that overflow interrupt hits.

The C code, followed by an objdump-ed disassembly. Note that in the interest of narrowing things down as much as possible, the main program just infinite-loops, as well as the default interrupt handler. Any pointers to stupid stuff I'm missing would be immensely helpful. Thanks!

Code: Select all | TOGGLE FULL SIZE
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>

ISR(__vector_default)
{
   for (;;)
      ;
}

#define nop() __asm__ __volatile__("nop\n\t")

int main( void )
{
   wdt_disable();

   DDRA = _BV( DDRA1 );    // set A0 to output pin
   uint16_t i;
   PORTA = _BV( PA1 );
   for ( i = 0; i < 0x3FFF; i += 1 )
   {
      nop();
   }
   PORTA = 0;
   for ( i = 0; i < 0x3FFF; i += 1 )
   {
      nop();
   }

   TCCR1A = 0x0;
   TCCR1B = _BV( CS10 );  // no prescale
   TIMSK = _BV( TOIE1 );  // enable overflow interrupt
   TCNT1 = 0x0;           // clear counter
   sei();                 // enable interrupts globally

   for (;;)
      ;
   return 0;
}


Code: Select all | TOGGLE FULL SIZE
blinky-simple:     file format elf32-avr


Disassembly of section .text:

00000000 <__vectors>:
   0:   12 c0          rjmp   .+36        ; 0x26 <__ctors_end>
   2:   2a c0          rjmp   .+84        ; 0x58 <__bad_interrupt>
   4:   29 c0          rjmp   .+82        ; 0x58 <__bad_interrupt>
   6:   28 c0          rjmp   .+80        ; 0x58 <__bad_interrupt>
   8:   27 c0          rjmp   .+78        ; 0x58 <__bad_interrupt>
   a:   26 c0          rjmp   .+76        ; 0x58 <__bad_interrupt>
   c:   25 c0          rjmp   .+74        ; 0x58 <__bad_interrupt>
   e:   24 c0          rjmp   .+72        ; 0x58 <__bad_interrupt>
  10:   23 c0          rjmp   .+70        ; 0x58 <__bad_interrupt>
  12:   22 c0          rjmp   .+68        ; 0x58 <__bad_interrupt>
  14:   21 c0          rjmp   .+66        ; 0x58 <__bad_interrupt>
  16:   20 c0          rjmp   .+64        ; 0x58 <__bad_interrupt>
  18:   1f c0          rjmp   .+62        ; 0x58 <__bad_interrupt>
  1a:   1e c0          rjmp   .+60        ; 0x58 <__bad_interrupt>
  1c:   1d c0          rjmp   .+58        ; 0x58 <__bad_interrupt>
  1e:   1c c0          rjmp   .+56        ; 0x58 <__bad_interrupt>
  20:   1b c0          rjmp   .+54        ; 0x58 <__bad_interrupt>
  22:   1a c0          rjmp   .+52        ; 0x58 <__bad_interrupt>
  24:   19 c0          rjmp   .+50        ; 0x58 <__bad_interrupt>

00000026 <__ctors_end>:
  26:   11 24          eor   r1, r1
  28:   1f be          out   0x3f, r1   ; 63
  2a:   cf ed          ldi   r28, 0xDF   ; 223
  2c:   cd bf          out   0x3d, r28   ; 61

0000002e <__do_copy_data>:
  2e:   10 e0          ldi   r17, 0x00   ; 0
  30:   a0 e6          ldi   r26, 0x60   ; 96
  32:   b0 e0          ldi   r27, 0x00   ; 0
  34:   ea e0          ldi   r30, 0x0A   ; 10
  36:   f1 e0          ldi   r31, 0x01   ; 1
  38:   02 c0          rjmp   .+4         ; 0x3e <__SP_H__>
  3a:   05 90          lpm   r0, Z+
  3c:   0d 92          st   X+, r0
  3e:   a0 36          cpi   r26, 0x60   ; 96
  40:   b1 07          cpc   r27, r17
  42:   d9 f7          brne   .-10        ; 0x3a <__do_copy_data+0xc>

00000044 <__do_clear_bss>:
  44:   10 e0          ldi   r17, 0x00   ; 0
  46:   a0 e6          ldi   r26, 0x60   ; 96
  48:   b0 e0          ldi   r27, 0x00   ; 0
  4a:   01 c0          rjmp   .+2         ; 0x4e <.do_clear_bss_start>

0000004c <.do_clear_bss_loop>:
  4c:   1d 92          st   X+, r1

0000004e <.do_clear_bss_start>:
  4e:   a0 36          cpi   r26, 0x60   ; 96
  50:   b1 07          cpc   r27, r17
  52:   e1 f7          brne   .-8         ; 0x4c <.do_clear_bss_loop>
  54:   0c d0          rcall   .+24        ; 0x6e <main>
  56:   57 c0          rjmp   .+174       ; 0x106 <_exit>

00000058 <__bad_interrupt>:
  58:   00 c0          rjmp   .+0         ; 0x5a <__vector_default>

0000005a <__vector_default>:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>

ISR(__vector_default)
{
  5a:   1f 92          push   r1
  5c:   0f 92          push   r0
  5e:   0f b6          in   r0, 0x3f   ; 63
  60:   0f 92          push   r0
  62:   11 24          eor   r1, r1
  64:   df 93          push   r29
  66:   cf 93          push   r28
  68:   cd b7          in   r28, 0x3d   ; 61
  6a:   de b7          in   r29, 0x3e   ; 62
   for (;;)
      ;
  6c:   ff cf          rjmp   .-2         ; 0x6c <__vector_default+0x12>

0000006e <main>:
}

#define nop() __asm__ __volatile__("nop\n\t")

int main( void )
{
  6e:   df 93          push   r29
  70:   cf 93          push   r28
  72:   00 d0          rcall   .+0         ; 0x74 <main+0x6>
  74:   cd b7          in   r28, 0x3d   ; 61
  76:   de b7          in   r29, 0x3e   ; 62
   wdt_disable();
  78:   88 e1          ldi   r24, 0x18   ; 24
  7a:   0f b6          in   r0, 0x3f   ; 63
  7c:   f8 94          cli
  7e:   81 bd          out   0x21, r24   ; 33
  80:   11 bc          out   0x21, r1   ; 33
  82:   0f be          out   0x3f, r0   ; 63

   DDRA = _BV( DDRA1 );    // set A0 to output pin
  84:   8a e3          ldi   r24, 0x3A   ; 58
  86:   90 e0          ldi   r25, 0x00   ; 0
  88:   22 e0          ldi   r18, 0x02   ; 2
  8a:   fc 01          movw   r30, r24
  8c:   20 83          st   Z, r18
   uint16_t i;
   PORTA = _BV( PA1 );
  8e:   8b e3          ldi   r24, 0x3B   ; 59
  90:   90 e0          ldi   r25, 0x00   ; 0
  92:   22 e0          ldi   r18, 0x02   ; 2
  94:   fc 01          movw   r30, r24
  96:   20 83          st   Z, r18
   for ( i = 0; i < 0x3FFF; i += 1 )
  98:   1a 82          std   Y+2, r1   ; 0x02
  9a:   19 82          std   Y+1, r1   ; 0x01
  9c:   06 c0          rjmp   .+12        ; 0xaa <main+0x3c>
   {
      nop();
  9e:   00 00          nop
   wdt_disable();

   DDRA = _BV( DDRA1 );    // set A0 to output pin
   uint16_t i;
   PORTA = _BV( PA1 );
   for ( i = 0; i < 0x3FFF; i += 1 )
  a0:   89 81          ldd   r24, Y+1   ; 0x01
  a2:   9a 81          ldd   r25, Y+2   ; 0x02
  a4:   01 96          adiw   r24, 0x01   ; 1
  a6:   9a 83          std   Y+2, r25   ; 0x02
  a8:   89 83          std   Y+1, r24   ; 0x01
  aa:   89 81          ldd   r24, Y+1   ; 0x01
  ac:   9a 81          ldd   r25, Y+2   ; 0x02
  ae:   ff e3          ldi   r31, 0x3F   ; 63
  b0:   8f 3f          cpi   r24, 0xFF   ; 255
  b2:   9f 07          cpc   r25, r31
  b4:   a0 f3          brcs   .-24        ; 0x9e <main+0x30>
   {
      nop();
   }
   PORTA = 0;
  b6:   8b e3          ldi   r24, 0x3B   ; 59
  b8:   90 e0          ldi   r25, 0x00   ; 0
  ba:   fc 01          movw   r30, r24
  bc:   10 82          st   Z, r1
   for ( i = 0; i < 0x3FFF; i += 1 )
  be:   1a 82          std   Y+2, r1   ; 0x02
  c0:   19 82          std   Y+1, r1   ; 0x01
  c2:   06 c0          rjmp   .+12        ; 0xd0 <main+0x62>
   {
      nop();
  c4:   00 00          nop
   for ( i = 0; i < 0x3FFF; i += 1 )
   {
      nop();
   }
   PORTA = 0;
   for ( i = 0; i < 0x3FFF; i += 1 )
  c6:   89 81          ldd   r24, Y+1   ; 0x01
  c8:   9a 81          ldd   r25, Y+2   ; 0x02
  ca:   01 96          adiw   r24, 0x01   ; 1
  cc:   9a 83          std   Y+2, r25   ; 0x02
  ce:   89 83          std   Y+1, r24   ; 0x01
  d0:   89 81          ldd   r24, Y+1   ; 0x01
  d2:   9a 81          ldd   r25, Y+2   ; 0x02
  d4:   ff e3          ldi   r31, 0x3F   ; 63
  d6:   8f 3f          cpi   r24, 0xFF   ; 255
  d8:   9f 07          cpc   r25, r31
  da:   a0 f3          brcs   .-24        ; 0xc4 <main+0x56>
   {
      nop();
   }

   TCCR1A = 0x0;
  dc:   8f e4          ldi   r24, 0x4F   ; 79
  de:   90 e0          ldi   r25, 0x00   ; 0
  e0:   fc 01          movw   r30, r24
  e2:   10 82          st   Z, r1
   TCCR1B = _BV( CS10 );  // no prescale
  e4:   8e e4          ldi   r24, 0x4E   ; 78
  e6:   90 e0          ldi   r25, 0x00   ; 0
  e8:   21 e0          ldi   r18, 0x01   ; 1
  ea:   fc 01          movw   r30, r24
  ec:   20 83          st   Z, r18
   TIMSK = _BV( TOIE1 );  // enable overflow interrupt
  ee:   89 e5          ldi   r24, 0x59   ; 89
  f0:   90 e0          ldi   r25, 0x00   ; 0
  f2:   20 e8          ldi   r18, 0x80   ; 128
  f4:   fc 01          movw   r30, r24
  f6:   20 83          st   Z, r18
   TCNT1 = 0x0;           // clear counter
  f8:   8c e4          ldi   r24, 0x4C   ; 76
  fa:   90 e0          ldi   r25, 0x00   ; 0
  fc:   fc 01          movw   r30, r24
  fe:   11 82          std   Z+1, r1   ; 0x01
 100:   10 82          st   Z, r1
   sei();                 // enable interrupts globally
 102:   78 94          sei

   for (;;)
      ;
 104:   ff cf          rjmp   .-2         ; 0x104 <__stack+0x25>

00000106 <_exit>:
 106:   f8 94          cli

00000108 <__stop_program>:
 108:   ff cf          rjmp   .-2         ; 0x108 <__stop_program>

sheu
 
Posts: 1
Joined: Thu Aug 19, 2010 4:53 am

Re: attiny2313 - infinite reset loop

by chatham on Sun Sep 26, 2010 3:32 pm

I don't personally have any experience with interrupts particularly, but this might help a little bit:

This might help:
http://www.avrfreaks.net/index.php?name ... 68&start=0

Also, from here:
http://www.nongnu.org/avr-libc/user-man ... rupts.html

Catch-all interrupt vector

If an unexpected interrupt occurs (interrupt is enabled and no handler is installed, which usually indicates a bug), then the default action is to reset the device by jumping to the reset vector. You can override this by supplying a function named BADISR_vect which should be defined with ISR() as such. (The name BADISR_vect is actually an alias for __vector_default. The latter must be used inside assembly code in case <avr/interrupt.h> is not included.)
OpenChord.org - Open Source kits to let you play Guitar Hero with a real guitar, or build your own Wii/PS3/USB controllers.

chatham
 
Posts: 144
Joined: Thu Feb 04, 2010 2:30 am

Re: attiny2313 - infinite reset loop

by zener on Mon Sep 27, 2010 3:33 am

Also make sure there is nothing in the configuration bits about reset on overflow. And if there is turn it off!

zener
 
Posts: 4567
Joined: Sat Feb 21, 2009 2:38 am

Re: attiny2313 - infinite reset loop

by uhe on Mon Sep 27, 2010 1:00 pm

sheu wrote:Any pointers to stupid stuff I'm missing would be immensely helpful. Thanks!

No, I didn't see any problems that should occur. This looks mostly like code I have for the ATtiny2313.
Which ISR did you use for the timer, ISR(TIMER1_OVF_vect)?
How do you know that the default ISR gets triggered?
Have you tried without the watchdog stuff at all?
"I have not failed. I've just found 10,000 ways that won't work." - Thomas Edison
uhe
 
Posts: 178
Joined: Mon Sep 03, 2007 4:50 pm
Location: metric world

Please be positive and constructive with your questions and comments.