[SOLVED] mega644 bug, avr-gcc bug or ...

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

Hi everybody,
i've been having some problems with the following piece of code. The uP is a mega644.
The USART is initialized as UART for 38400@16MHz, only for transmission.
However, if I try to send something to the UART, the 644 will go back to execute things at address 0x0000. The MCUSR shows that there is no external or power on reset source (it shows 0 as its value).
I might have a hardware problem maybe, or is it a mega644 bug?

here it's main.c

#include "globals.h"

extern void mytest(void);

int main()
{
	u08 st = MCUSR;
	MCUSR = 0;
	
	UBRR0L = (unsigned char)(51);      // inits midi!
	UBRR0H = (unsigned char)(51 >> 8);
	
	UCSR0A = (1<<U2X0);
	
	UCSR0B =  (1<<TXEN0) ;

	UCSR0C =  (1<<UCSZ01) | (1<<UCSZ00);
	
	setbit(DDRD,1);
	clrbit(DDRD,0);

	//fin usart init
	UDR0 = st;
	
	for(;;)
	{
		mytest();	//nada mas!
	}
	
	while(1);
	
	return 1;
}

mytest.c

void mytest(void)
{
	return;
}

globals.h just defines testbit(), setbit(), etc. along with some types (u08, u16, etc).

If I don't call mytest() in main then everything is fine, the avr never goes back to the reset vector.

I already tried with two different atmega644, and the same applies to both of them.

Thanks!

Last Edited: Wed. Sep 19, 2007 - 02:57 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'd guess that you are not building for the chip you are using, and the stack pointer is out in space somewhere. I'd expect an AVR I/O include file somewhere to get "UBRR0H" etc.

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Lee, thanks for the reply.
I'm building for the right uP, my Makefile is configured with MCU = atmega644 (using WinAVR and MFile here).

I thought of that too.
The strange thing is that the reset happens only if I send a character to the USART.
I thought something would be causing a short circuit there, but I've found nothing.

I just made another test here.. No USART involved in the code, just turning something on if the uP resets, and off when it's running.

Strangely when I send chars from the PC to the uP, the avr resets.. I believe there is a hardware thing, but I still can't find the cause.

thanks!

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

here is the code for what I said above..

int main()
{
	setbit( PORTB, 0 );
	setbit( DDRB, 0 );
	
	for(;;)
	{
		clrbit( PORTB,0 );
		mytest();	//nada mas!
	}
      return 1;
}

If I call test() and send something to the UART (which is completely disabled) the uP will reset itself.
If I comment the test() call, it won't.

I'll keep investigating this matter..

thanks once again.

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

Is there a bootloader that is enabling the USART and associated interrupt, then using the bits in MCUSR (IIRC) to shift the vector table to your application section? That would leave the USART enabled, and cause a reset when the now non-existant vector fires.

Had something like that happen to me once, with the Butterfly bootloader setting USART bits I wasn't expecting - that was "fun" to debug!

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

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

Dean,
I don't use a bootloader, and the fuse bits are programmed to start from 0x0000.

I still can't imagine what is causing this behaviour. I'm using a FT232 to connect the RS232 TTL level signals to the USB port in my laptop. Signals are routed right.

If at least the problem was always there, but it changes depending on mytest() call.

Thanks again,
Carlos

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

just another thing I found..
I compiled the same code with IAR AVR compiler (just small changes about include files) and the AVR won't reset on any test.

Also, I tried routing the FT232 TX output to different pins, apart from the AVRs RX one. I found that the only pin which causes trouble is the RX one, just that one.

Still strange, looks like some USART interrupts are set up somewhere, but where?
AVRStudio shows everything "clean" when simulating on the PC.

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

I just built this, for globals.h I used:

#include "avr/io.h" 
typedef unsigned char u08;
#define setbit(port, bit)	port |= (1<<bit)
#define clrbit(port, bit)	port &= ~(1<<bit)

Can you confirm that you .lss contents are the same:

eric.elf:     file format elf32-avr

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         000000e0  00000000  00000000  00000054  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .stab         00000378  00000000  00000000  00000134  2**2
                  CONTENTS, READONLY, DEBUGGING
  2 .stabstr      00000071  00000000  00000000  000004ac  2**0
                  CONTENTS, READONLY, DEBUGGING
  3 .debug_aranges 00000040  00000000  00000000  0000051d  2**0
                  CONTENTS, READONLY, DEBUGGING
  4 .debug_pubnames 00000038  00000000  00000000  0000055d  2**0
                  CONTENTS, READONLY, DEBUGGING
  5 .debug_info   000000c9  00000000  00000000  00000595  2**0
                  CONTENTS, READONLY, DEBUGGING
  6 .debug_abbrev 00000084  00000000  00000000  0000065e  2**0
                  CONTENTS, READONLY, DEBUGGING
  7 .debug_line   00000146  00000000  00000000  000006e2  2**0
                  CONTENTS, READONLY, DEBUGGING
  8 .debug_frame  00000040  00000000  00000000  00000828  2**2
                  CONTENTS, READONLY, DEBUGGING
  9 .debug_str    00000081  00000000  00000000  00000868  2**0
                  CONTENTS, READONLY, DEBUGGING
 10 .debug_loc    00000013  00000000  00000000  000008e9  2**0
                  CONTENTS, READONLY, DEBUGGING
Disassembly of section .text:

00000000 <__vectors>:
   0:	0c 94 38 00 	jmp	0x70	; 0x70 <__ctors_end>
   4:	0c 94 55 00 	jmp	0xaa	; 0xaa <__bad_interrupt>
   8:	0c 94 55 00 	jmp	0xaa	; 0xaa <__bad_interrupt>
   c:	0c 94 55 00 	jmp	0xaa	; 0xaa <__bad_interrupt>
  10:	0c 94 55 00 	jmp	0xaa	; 0xaa <__bad_interrupt>
  14:	0c 94 55 00 	jmp	0xaa	; 0xaa <__bad_interrupt>
  18:	0c 94 55 00 	jmp	0xaa	; 0xaa <__bad_interrupt>
  1c:	0c 94 55 00 	jmp	0xaa	; 0xaa <__bad_interrupt>
  20:	0c 94 55 00 	jmp	0xaa	; 0xaa <__bad_interrupt>
  24:	0c 94 55 00 	jmp	0xaa	; 0xaa <__bad_interrupt>
  28:	0c 94 55 00 	jmp	0xaa	; 0xaa <__bad_interrupt>
  2c:	0c 94 55 00 	jmp	0xaa	; 0xaa <__bad_interrupt>
  30:	0c 94 55 00 	jmp	0xaa	; 0xaa <__bad_interrupt>
  34:	0c 94 55 00 	jmp	0xaa	; 0xaa <__bad_interrupt>
  38:	0c 94 55 00 	jmp	0xaa	; 0xaa <__bad_interrupt>
  3c:	0c 94 55 00 	jmp	0xaa	; 0xaa <__bad_interrupt>
  40:	0c 94 55 00 	jmp	0xaa	; 0xaa <__bad_interrupt>
  44:	0c 94 55 00 	jmp	0xaa	; 0xaa <__bad_interrupt>
  48:	0c 94 55 00 	jmp	0xaa	; 0xaa <__bad_interrupt>
  4c:	0c 94 55 00 	jmp	0xaa	; 0xaa <__bad_interrupt>
  50:	0c 94 55 00 	jmp	0xaa	; 0xaa <__bad_interrupt>
  54:	0c 94 55 00 	jmp	0xaa	; 0xaa <__bad_interrupt>
  58:	0c 94 55 00 	jmp	0xaa	; 0xaa <__bad_interrupt>
  5c:	0c 94 55 00 	jmp	0xaa	; 0xaa <__bad_interrupt>
  60:	0c 94 55 00 	jmp	0xaa	; 0xaa <__bad_interrupt>
  64:	0c 94 55 00 	jmp	0xaa	; 0xaa <__bad_interrupt>
  68:	0c 94 55 00 	jmp	0xaa	; 0xaa <__bad_interrupt>
  6c:	0c 94 55 00 	jmp	0xaa	; 0xaa <__bad_interrupt>

00000070 <__ctors_end>:
  70:	11 24       	eor	r1, r1
  72:	1f be       	out	0x3f, r1	; 63
  74:	cf ef       	ldi	r28, 0xFF	; 255
  76:	d0 e1       	ldi	r29, 0x10	; 16
  78:	de bf       	out	0x3e, r29	; 62
  7a:	cd bf       	out	0x3d, r28	; 61

0000007c <__do_copy_data>:
  7c:	11 e0       	ldi	r17, 0x01	; 1
  7e:	a0 e0       	ldi	r26, 0x00	; 0
  80:	b1 e0       	ldi	r27, 0x01	; 1
  82:	e0 ee       	ldi	r30, 0xE0	; 224
  84:	f0 e0       	ldi	r31, 0x00	; 0
  86:	02 c0       	rjmp	.+4      	; 0x8c <.do_copy_data_start>

00000088 <.do_copy_data_loop>:
  88:	05 90       	lpm	r0, Z+
  8a:	0d 92       	st	X+, r0

0000008c <.do_copy_data_start>:
  8c:	a0 30       	cpi	r26, 0x00	; 0
  8e:	b1 07       	cpc	r27, r17
  90:	d9 f7       	brne	.-10     	; 0x88 <.do_copy_data_loop>

00000092 <__do_clear_bss>:
  92:	11 e0       	ldi	r17, 0x01	; 1
  94:	a0 e0       	ldi	r26, 0x00	; 0
  96:	b1 e0       	ldi	r27, 0x01	; 1
  98:	01 c0       	rjmp	.+2      	; 0x9c <.do_clear_bss_start>

0000009a <.do_clear_bss_loop>:
  9a:	1d 92       	st	X+, r1

0000009c <.do_clear_bss_start>:
  9c:	a0 30       	cpi	r26, 0x00	; 0
  9e:	b1 07       	cpc	r27, r17
  a0:	e1 f7       	brne	.-8      	; 0x9a <.do_clear_bss_loop>
  a2:	0e 94 57 00 	call	0xae	; 0xae 
a6: 0c 94 6f 00 jmp 0xde ; 0xde <_exit> 000000aa <__bad_interrupt>: aa: 0c 94 00 00 jmp 0 ; 0x0 <__vectors> 000000ae
: extern void mytest(void); int main() { ae: 94 b7 in r25, 0x34 ; 52 u08 st = MCUSR; MCUSR = 0; b0: 14 be out 0x34, r1 ; 52 UBRR0L = (unsigned char)(51); // inits midi! b2: 83 e3 ldi r24, 0x33 ; 51 b4: 80 93 c4 00 sts 0x00C4, r24 UBRR0H = (unsigned char)(51 >> 8); b8: 10 92 c5 00 sts 0x00C5, r1 UCSR0A = (1<<U2X0); bc: 82 e0 ldi r24, 0x02 ; 2 be: 80 93 c0 00 sts 0x00C0, r24 UCSR0B = (1<<TXEN0) ; c2: 88 e0 ldi r24, 0x08 ; 8 c4: 80 93 c1 00 sts 0x00C1, r24 UCSR0C = (1<<UCSZ01) | (1<<UCSZ00); c8: 86 e0 ldi r24, 0x06 ; 6 ca: 80 93 c2 00 sts 0x00C2, r24 setbit(DDRD,1); ce: 51 9a sbi 0x0a, 1 ; 10 clrbit(DDRD,0); d0: 50 98 cbi 0x0a, 0 ; 10 //fin usart init UDR0 = st; d2: 90 93 c6 00 sts 0x00C6, r25 for(;;) { mytest(); //nada mas! d6: 0e 94 6e 00 call 0xdc ; 0xdc da: fd cf rjmp .-6 ; 0xd6 000000dc : void mytest(void) { dc: 08 95 ret 000000de <_exit>: de: ff cf rjmp .-2 ; 0xde <_exit>

In particular, the key thing in here is:

00000070 <__ctors_end>:
  70:	11 24       	eor	r1, r1
  72:	1f be       	out	0x3f, r1	; 63
  74:	cf ef       	ldi	r28, 0xFF	; 255
  76:	d0 e1       	ldi	r29, 0x10	; 16
  78:	de bf       	out	0x3e, r29	; 62
  7a:	cd bf       	out	0x3d, r28	; 61

which is setting the stack pointer to 0x10FF which is the RAMEND figure defined in iom644.h

This codes works exactly as expected in the simulator.

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

To check whether it really is an interrupt firing you could write a catch-all isr and see if it is ever entered. But since there's no sei() anywhere in your program, I'd guess it is something else. The stack pointer would be my first guess.

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

Well, I think I solved it. It was a hardware thing.

I forgot to add the 33pF caps to the new PCB.
The USART pin is near the XTAL ones in the AVR, that seemed to be causing some noise when clocking the AVR.
It's strange knowing that the only pin which would cause such behaviour is the RX one, who knows.

Just a so stupid thing. It looks strange, since it resets the AVR by "software" (going to address 0x000).

Well, thanks to everyone who helped here.

Carlos

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

Oh so it wasn't a bug in the compiler or the silicon after all? I'm totally stunned given that both are known to be riddled with bugs and have hardly ever been tested by anybody.

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

It looks like it.
I don't know about bugs in avr-gcc, are there so many?

I mean, should I buy a commercial compiler if I'm really working with it?
Maybe this should be another topic.

thanks again

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

Clearly sarcasm does not cross the international divide then?

(you are not the first to postulate that the silicon or the compiler/assembler they are using is the source of their problems when it almost NEVER is ;))

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

well actually the problem might be I'm not that fuild in english.. nevermind, I won't start a debate on that.

I've been using avr-gcc for quite a while, looks stable but...
The winavr suite is really nice. Makefiles and avrdude make things quick and easy.
I hope I never have to change to another compiler.

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

Man, I gota tell ya...

I love the ImageCraft ICCAVR C compiler!!!

It cost more then "Free " AVR-GCC. It cost less then IAR. But I have found ICCAVR to satisfy all of my AVR programming needs.

You can avoid reality, for a while.  But you can't avoid the consequences of reality! - C.W. Livingston