Runtime decision: ATMega128 or ATmega2560?

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

This is a bit of a long introduction to the question...

I have a system with both an ATmega128 and ATmega2560. Each processor can be downloaded with new firmware in situ. As a complete fubar on my part I forgot to make sure the beginning of each file contain an indicator for which processor the file is intended. :oops: In other words, the user can accidently download the wrong firmware file into the processor.

Yeah, I know, stupid. Luckily, we haven't had this actually happen, and the external support software checks the file name before downloading. For the most part it won't happen.

But, I'd still like to throw in a last ditch "what if" in the code itself. Something that recognizes it is in the wrong processor and drops into the bootloader.

Now for the question: How would the code recognize the type of processor it is running in? There is a processor signature, but that appears to be accessible only from JTAG/ISP (unless my 3 readings of the datasheet missed it).

The only thing I can some up with is to do a subroutine call and look at how many bytes were pushed on the stack -- ATmega128 will push 2 bytes for the return address, while the 2560 will push 3.

Can anyone else see an easier method? Or, even better, is there a way to read the processor signature bytes from inside the processor?

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

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

Haven't checked but presumably the 2560 has more RAM than the 128 so a write/read/verify on chosen addresses that exist in one CPU but not the other should verify which one it is but actually I think I prefer your push 2/3 idea anyway!

Cliff

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

The '2560 has a SIGRD bit, but I haven't used it.

Have your ISP programming process do a signature match. Or is this a bootload?

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

You might try writing to the RAMPZ register with a value greater than 1. The 128 will not accept such a value, but the 2560 will. In the 128 they suggest you do not write 1's into higher order bits but you should be able to write 0's after the test.
Dave Raymond

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

Thanks for the answers -- I'll try each and (eventually) let everyone know what I chose.

Cliff: You're right -- the 128 has 4K while the 2560 has 8K. Also, in my application, the 2560 has external RAM while the 128 does not. Good idea!

Theusch: The processor is self-programming, no ISP or JTAG attached. Ergo the need for code that recognizes the processor type it is running in.

Thanks again!

Stu

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

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

Distinguishin between the ATmega128 and ATmega256x is simpler than
between an ATmega128x and 256x. If you're using the default stack
pointer value, the new device's RAM end (and thus SP init value) is
0x2200, while the ATmega128 had 0x1100.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

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

While the '2560 appears to have SPH/SPL at an initial value at reset, I beleive that the '128 does not have this new feature and the datasheet says they will be 0/0. Which may also be good enoug for this purpose. :) Assuming the code grabs this info at some point immediately following a reset.

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

Jörg: That works if the code is in the right processor. Keep in mind the scenario: I have code intended for a 128 loaded in a 2560 (or vice versa). The SP init (and RAM end?) value is loaded from flash, so that won't work. Actually, now that I think about it, the SP location really will be a problem here -- If I'm the 2560 code residing in a 128, my stack pointer will point to the dead zone.

theusch: That might work -- I'd have to hack the reset vector, but that's not the end of the world.

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

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

Have you tried the signature read on the '2560? If it works well, then try it on a '128 to make sure it doen't lose its mind. If you get a valid '2560 signature it is a '2560. If you don't, it isn't.

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

Another thing would be if you know they have different fuse settings:
unlike the signature, the fuses can be read out via LPM.

But I think the ultimatively best solution would be to rely on some
peripheral. For example, start timer 0. This is control register
0x25 (in IO space) on the ATmega256x, which should start the timer.
Perform two successive reads on IO register 0x26, and see whether
the results differ: it's an ATmega256x then. For the ATmega128, your
0x25 access would have started timer 2 instead, but 0x26 is ICR1L
there which won't change its value. I think you'll be able to find
more of these examples, and best of all: you can run them at the
beginning of main() (or even as part of the startup code) so they
don't need a working stack at all.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

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

theusch wrote:
Have you tried the signature read on the '2560?

Cool Lee. How do I do that, programmatically? That was a question I asked originally. Keep in mind the processor cannot tickle it's own JTAG or ISP port.

As I said in my first post, I read the datasheet for an hour and did not see how to read the signature bytes fom a program running on the processor. From JTAG and ISP, sure! From a program, nope!

I'm sure I missed it. Just didn't couldn't find it in the FINE datasheet. :evil:

Stu

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

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

Jörg: Fuse settings are an idea I hadn't thought of. Thanks!

Stu

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

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

stu_san wrote:
theusch wrote:
Have you tried the signature read on the '2560?

Cool Lee. How do I do that, programmatically? That was a question I asked originally. Keep in mind the processor cannot tickle it's own JTAG or ISP port.

As I said in my first post, I read the datasheet for an hour and did not see how to read the signature bytes fom a program running on the processor. From JTAG and ISP, sure! From a program, nope!

I'm sure I missed it. Just didn't couldn't find it in the FINE datasheet. :evil:

Stu

It's on page 331 of the ATmega2560 datasheet.

- Point the Z-pointer at one of the following addresses:
0x0000 = signature byte 1
0x0001 = Factory default RC Oscillator Calibration Byte
0x0002 = signature byte 2
0x0004 = signature byte 3

- Set the SIGRD and SPMEN bits in SPMCR.

- Within 3 clock cycles, execute an LPM instruction. The desired byte from the signature space will be loaded into the destination register.

This is not a documented feature in the ATmega128, though, so you may want to test it to see what happens in a '128 if you attempt this procedure. At the most benign, you may just end up reading back the low bytes of the first three Flash words. At worst, you may give the ATmega128 brain damage and cause unexpected code execution.

Any result other than a valid ATmega2560 signature can be assumed to be a test failure, though.

(I'm not even sure if the SPMCR register is located in the same I/O location in a '128 as it is in a '2560...)

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

Quote:

As I said in my first post, I read the datasheet for an hour and did not see how to read the signature bytes fom a program running on the processor.

Search the datasheet for "signature". The first hit is the SIGRD bit in SPMCSR.

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

> (I'm not even sure if the SPMCR register is located
> in the same I/O location in a '128 as it is in a '2560...)

Completely different. It's TIMSK in the '128. So the LPM will
probably read the flash contents of addresses 0/2/4 then.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

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

Quote:
It's on page 331 of the ATmega2560 datasheet.

- Point the Z-pointer at one of the following addresses:
0x0000 = signature byte 1
0x0001 = Factory default RC Oscillator Calibration Byte
0x0002 = signature byte 2
0x0004 = signature byte 3

- Set the SIGRD and SPMEN bits in SPMCR.

- Within 3 clock cycles, execute an LPM instruction. The desired byte from the signature space will be loaded into the destination register.

Thank you lfmorrison!! I really did try to find that, as I knew it had to be there!

Thanks also to Lee, Jörg, and everyone else who responded. I'm sure I can get what I need now!

Stu

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!