Differences between ATMega1284p and ATMega644p?

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

I am trying to run on a 1284p a piece of code that has been consistently running fine on a 644p (for the moment not taking advantage of the extra memory ; and no plan to use Timer3). I get two kinds of problems:
- infrequent freezes or crashes after extended periods of use.
- a problem that I am currently working on isolating from my code, and which amounts to short glitches in the PWM output, the value of which is updated from the timer 1 overflow interrupt. To give you an idea of the kind of weirdness I have to deal with, the glitch disappears when I comment a call to a function, but is still there when I comment the body of the function (in which case it's just compiled into a call and a ret).

I am comparing the assembly listings of the code generated by gcc for both targets and the only difference I can see is the extra push/pop in interrupt handlers for saving the content of the rampz register. Besides that the generated code is exactly the same. I'm swapping chips in and out of the same prototype board, fuses are set similarly for both chips.

What could explain the different behaviour? My code hitting an undefined behaviour that goes unnoticed on the 644p but causes havoc on the 1284p? Is there any new "feature" of the 1284p that needs special handling? Any known 1284p oddities? I've tried scanning the datasheets of the 644p and 1284p side by side to look for obvious differences and things that would need to be done differently, but I haven't caught anything besides the availability of a fourth timer.

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

I thought you didnt need rampz until you got more than 64k words of flash? Are all the call and rets 3 byte addresses? Do the interrupt handlers also save and restore rampz?

Imagecraft compiler user

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

bobgardner wrote:
I thought you didnt need rampz until you got more than 64k words of flash?
You need to use RAMPZ to access Flash above 64K bytes using ELPM. Three-byte return address are necessary only when the Flash size exceed 128K bytes.

Don Kinzer
ZBasic Microcontrollers
http://www.zbasic.net

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

The code that saves and restores rampz in an interrupt handler is not mine, it is generated by gcc (Forgot to mention that my program is C/C++). Will try to get a small reproducible subset of it and will post it here.

To be more clear, the only difference between the code compiled for the 644p and the 1284p is the addition of:

5e3e:	0b b6       	in	r0, 0x3b	; 59
5e40:	0f 92       	push	r0
...
5fba:	0f 90       	pop	r0
5fbc:	0b be       	out	0x3b, r0	; 59

At the entry and exit of the interrupt handlers ; the extra entries in interrupt tables ; and the use of elpm when populating the RAM at startup (__do_copy_data). None of those are my business and I don't see anything wrong in them. Still, there's this difference of behavior of my program on both chips I can't explain.

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

I managed to strip almost everything from my program except the small subset of functionality that allows the problem to be observed.

http://dl.dropbox.com/u/612135/w...

To give you a broader context, my project is (yet another) synthesizer. The MCU is clocked at 20Mhz. The PWM outputs associated with Timer 1&2 are used to generate a waveform and control signals. There's a loop filling a ring buffer with blocks of 40 audio samples, and in the timer ISR, samples are pulled from the buffer and written to the PWM output. If correctly filtered, the output of the program above should be a sine wave. The bug consists in discontinuities/phase resets in the waveform, on the 1284p only.

Now the very weird stuff:
- In order to reproduce the problem I need to have those static objects in foo.cc/bar.cc (If I don't link with those files, I can't reproduce the bug).
- If I change the line "OCR2B = 200;" line to 255, the problem doesn't occur. There seems to be a relationship between the value written to OCR2B and the frequency of glitches.

The fact that this bug requires these two conditions really puzzles me - I fail to see any connection between what those changes do and what could a glitch in the output. If you have an idea let me know!

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

Swap the order of the 1st 2 include files and recompile for effect?

Imagecraft compiler user

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

Generated code is the same. Sacrificing a chicken didn't help either.

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

Strange that the complier generates the extra push and pop for rampz even though the register ISN'T used by the ISR. The compiler should read the source in two passes, one pass to parse the source and the second to generate the code. By the second pass it would know that saving the rampz isn't required for the routine. I guess a canned ISR preamble and postable are used for ALL ISR's on a given cpu. Note that the stack size is different on the two cpu's and the initial location of the stack pointer might be an issue, or maybe the '128 has more on board cpu registers which means the on board ram starts at a higher location? Also the '128 has more interrupt vectors(?) and the '644 code doesn't handle some of them?

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

pichenettes wrote:
I am comparing the assembly listings of the code generated by gcc for both targets and the only difference I can see is the extra push/pop in interrupt handlers for saving the content of the rampz register. Besides that the generated code is exactly the same.
kscharf has an excellent point. Given the difference in the interrupt table lengths and GCC always filling in the ISR(BADISR_vect) jump addresses, the generated code couldn't possibly be the same except for the interrupt handlers for both chips. This will also cause the reset vector address to change. Something is very wrong here.

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

The reset vector is always at zero. However the start of the code now might overlap an interrupt vector present on the '128 not present on the '644.

Check the .map file to see what the REAL differences are!

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

Sorry, I didn't mean the address of the reset vector, I meant the reset vector JMP address which is different with a different length interrupt vector table.

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

Sorry if I wasn't clear about this... When I said "the generated code is the same" I meant "the code generated from my C application code". As pointed by kscharf there are indeed subtle differences outside of this (larger interrupt table to accommodate for Timer3 interrupts, use of rampz/elpm when copying data from flash to RAM in __do_copy_data). Here's a dump of the 1284p version, with, in bold, things that have changed with respect to the 644p (ignoring the address translations):

http://typewith.me/mVSxPky55i

Is there another tool I can use to look at the data?

I'm really stuck on this... Either my code is incorrect / missing something and happens to work on the 644p (and 328p too) by chance ; or there's something fundamentaly different on the 1284p...

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

Thanks for clarifying things and posting your disassembly code.

0856H-AVR-07/09 AVR Instruction Set wrote:
The result of these combinations is undefined:
LPM r30, Z+
LPM r31, Z+
Look at address 30a:
30a:       f4 91      lpm      r31, Z+
30c:       e0 2d      mov      r30, r0
30e:       09 94      ijmp

[edit] Eugene is correct the actual opcode is LPM r30, Z.

Last Edited: Sat. May 29, 2010 - 03:51 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
30a:       f4 91      lpm      r31, Z+

I think this is just an issue with objdump or whatever utility generates this. It has nothing to do with 1284/644. I have seen this on other micros too. The F4 91 instruction does not have a "+".

Eugene

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

Quote:

The reset vector is always at zero.

Except when BOOTRST is set

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

Does the 1284 have 16k of ram? Does this mean the stack is 8k farther down in ram than on the 644? (I have no idea why this would be a problem)

Imagecraft compiler user

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

I think this sounds like a bug that the slight change in timing is showing up. I think you should be checking for volatile and atomic usage.