Using SPM on Xmega from application section using a method in bootloader section

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

Hi all,

 

I am using an ATxmega128A3U and am trying to have my application modify the flash from the application section using some bootloader hack, but it doesn't work as expected.

 

I have linked sp_driver.S from AVR1316 application note into my C application. I have modified it to have all methods inside a .bootloader section. Using a modified linker script I moved the .bootloader section to the end of the flash (address 0x1FE00 to be specific). Using objcopy I have marked the .bootloader section to be allocated so that avrdude transfers both the .text and .bootloader sections to the chip. I have read back the contents and double checked, the code is on the chip at the right addresses. It runs without crash, but the flash is not modified. The list file shows the moved methods like this:

 

0001ff56 <SP_CommonSPM>:
   1ff56: fc 01         movw  r30, r24
   1ff58: 40 93 ca 01   sts 0x01CA, r20
   1ff5c: 2d e9         ldi r18, 0x9D ; 157
   1ff5e: 20 93 34 00   sts 0x0034, r18
   1ff62: e8 95         spm
   1ff64: 11 24         eor r1, r1
   1ff66: 3b bf         out 0x3b, r19 ; 59
   1ff68: 80 e2         ldi r24, 0x20 ; 32
   1ff6a: 80 93 41 06   sts 0x0641, r24
   1ff6e: 08 95         ret

 

In my opinion the spm instruction should be allowed to do its work when executed here, right? It is not necessary that some boot fuse is set for this, correct?

 

I call all the code like this:

 

  uint8_t x[512];
  memset(x, 0xAA, sizeof(x));
  SP_LoadFlashPage(x);

  SP_EraseWriteApplicationPage(0);
  SP_WaitForSPM();

 

I would expect the first page of the flash to get 0xAAAA, but when reading back using avrdude the flash is still in tact. What am I missing?

 

I know there are plenty of posts on this here, but all seem to suggest this construction could work.

 

Hope someone can point out my mistake.

 

Thanks!

 

This topic has a solution.

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

Some bootloaders will disable SPM when they exit to the application. Maybe yours does that.  The SPM will be enabled after the next reset. 

 

The sp_driver.s function is SP_LockSPM.  It sets the NVM_SPMLOCK_bm bit in the NVM control B register.  This bit gets cleared at reset.

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

I have checked the NVM.CTRLB register before and after my SP_* calls and it is and remains all zeros, so I don't think this is the problem.

 

Also know that I don't have a bootloader and my application is not doing the SPM lock. I only have my own application (starting from address 0) but with the SP_* methods moved into the bootloader section to allow them (I had hoped) to write stuff into flash for me.

 

I have checked the lockbits too, they are 0xFF, which means no locks if I read correctly.

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

I can't help you.  I don't know assembler.  Maybe you have something wrong there.   Your SP_CommonSPM is somewhat different from what I see in the sp_driver.s used in my bootloader, but that doesn't mean it is wrong.

 

If you have an on chip debugger, that might give you a clue.

 

I have attached my sp_driver.s in case you want to look.  I had to add a .txt suffix because this forum won't upload a file ending in .s

Attachment(s): 

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

Thanks for the help anyway. I might be on to something where the calling between C en assembler is not going properly. I experience problems with the read methods also, I converted one to C and that does work. I will compare list files and hopefully I figure out the problem today.

 

Anyway my assembler is the same as in you attachment, except for my addition of:

 

  1ff68: 80 e2         ldi r24, 0x20 ; 32
   1ff6a: 80 93 41 06   sts 0x0641, r24

 

This turns on my test LED so that I am sure the code is being called.

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OMG reading the datasheet again I noticed that the 8K bootloader is on top of the 128K flash. (For Mega's it used to be part of the Flash at the end). So changing my linker script to have the bootloader methods start from 0x20000 made it work. Nice.
 

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

I'm glad you are successful.

 

I may try something like that for testing purposes.  I'm writing a bootloader.  It's much easier for me to test it when it is part of an application.  I can test reading flash this way but of course I can't test writing to flash unless I use your method.