Bootloader and Atmel 2560 - How to jump?

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

HELP!!!

I can't seem to figure out how to jump to address 0 from bootload space. The 2560 is not the same as other chips and I suspect that the RAMPZ has something to do with it. I have tried all kinds of tricks, but nothing works. The normal..

asm volatile ("clr r30\n clr r31\n ijmp\n":);

does not work.

Anybody know how to make a 2560 work?
Thanx

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

The JMP instruction has a 4 million word address range. It will reach.

Look in the data sheet at the EIJMP instruction and the EIND register.

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

Thanx for reply

I am not an assembler person ... how do I use the EIND reg. The nemonics is not stated in 2560 datasheet. Tried a few things .. but nothing works yet

asm volatile("clr r30");
asm volatile("clr r31");
EIND = 0;
asm volatile("eijmp");

Frustration!!

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

Quote:

how do I use the EIND reg.

What information beyond that found in a datasheet search for "EIND" do you need?

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

Why it must be assembler?

Why you not write C:

((void(*)(void))(char *)0x0000)(); // jump to 0x0000

Peter

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

EIND is an AVR register name and EIJMP is an AVR instruction. EIND appears in the data sheet section 7.6.2 EIND – Extended Indirect Register, section 33 Register Summary and section 34 Instruction Set Summary. IJMP appears in the data sheet section 7.6.2 EIND – Extended Indirect Register and section 34 Instruction Set Summary.

It is up to the compiler writer and/or assembler writer to implement the registers and instructions ATMEL puts into each AVR chip. You appear to be using a C compiler to write some assembly code. First check your C compiler documentation too see if the ATmega2560 is supported or not (not all compilers support this chip and even then of the compilers that do, usually only the latest compiler releases support this chip). Then check your compiler/assembler documentation to find out how EIND and EIJMP are implemented.

I noticed in your first example that your compiler/assembler uses IJUMP while ATMEL uses IJMP, so your compiler/assembler does not follow the ATMEL naming conventions. This means that you must use your compiler/assembler documentation or get technical support from the compiler/assembler people. ATMEL cannot be held responsible for their actions.

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

Still no joy.

OK .. let me start from the beginning and see where I am going wrong.
It might be that I am indeed getting a proper jump, but something else is wrong. First off .. using winavr.

I have compiled a bootloader program that is programmed into the boot space of the Atmel 2560. When only this code is programmed, the programs runs … jumps and comes back as a result of nothing else being programmed. When this code was programmed all memory was erased prior to programming.

Step two .. remove fuse to erase memory prior to programming and program my normal code which sits at address zero. There is no org statements or such like directives.

Reset micro … bootloader comes up and then after jumping … micro is in never-never land.

Ok .. reset fuse for boot vector to zero. Normal program now runs fine, but bootloader no longer accessible.

Quiestion: what about interrupt vector tables. Is it OK to them in both programs?
Anything I am doing wrong? I have read everything I can find on the subject, but appear stuck. If I recall, I did get a Mega8 working fine, but having trouble with the 2560.

Thanx

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

asm volatile("jmp 0");

I'm using anolder version of gcc, so I can't compile for the 2560, but simply making an asm project with one instruction 'jmp 0' results in-
00000000: 940C0000 JMP 0x00000000

940C0000 is the jmp isnstruction which loads the PC with 0, which is what you want.

Look at the lss listing to see what's happening in your case, or run the simulator.

ijmp/icall use the Z register, and can only address 64k(words)/128k(bytes), and load PC16:22 with 0 (the instruction datasheet should say for icall- 'Calls to a subroutine FROM within the entire 4M (words)Program memory TO the first 64k (words) program memory'). So a way is needed to address the entire program memory, so eicall/eijmp do the trick, by loading the upper PC bits 16:22 from the EIND register.

RAMPZ is used with ELPM and SPM only.

Your latest post-

you are switching the interrupt vector table back to the application section, right?

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

Feedback …. Good new … success … but problem was a nasty to find!!!

I made up a small ‘boot’ program that had almost nothing in it. This was an attempt to be able to read the list file more clearly and see what the compiler was doing. So basically is was just a jump routine. … and it worked – Hooray :D

The jump instruction used was as per Mike B’s suggestion. So that bit of code was working all along

asm volatile("clr r30");
asm volatile("clr r31");
EIND = 0;
asm volatile("eijmp");

I then went back to my main bootloader program and cleared out a lot of code. I then started adding chunks at a time until the jump no longer functioned. I found that as soon as I initialized my SPI, the bootloader no longer worked.

The register SPCR had been set to 0x5C and causing all the grief. So by resetting this to 0x00 before the jump, everything worked.

Not sure why this is an issue though. Maybe somebody could explain why the SPI is causing grief. As can be noted, the actual interrupt had not been enabled.

Regards the C functions …

((void(*)(void))(char *)0x0000)(); // jump to 0x0000

All this does is clear R30 and R31. The high order page bit is still untouched.

Thanx to all you guys that took the time to post. I appreciate your comments.