Writing fuses and lockbits through PDI and code line

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

Hi guys, sorry for another question about this topic, however, none of the posts that I have found helped me. I tried to follow the instructions presented here, still, nothing changed the fuses.

 

My problem is that I have a product that is going into production and program lockbits and fuses one at a time is time expensive. What I need is to introduce a command into the program, which will be compiled into a .hex or .elf file. This file I will give to the operator who will program the microcontroller (an ATXMEGA128A1U).

 

I am using Atmel Studio 7.0.1417 and JTAGICE3. I wish to program using the Device Programming tools.
Is that possible?

 

here is a bit of the code:

#include "defines.h"
#include ... //more includes here

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

//global variables here...

//I have tried those three methods -- NOT AT THE SAME TIME

FUSES =
{
	 0xff,
	0x00,
	0xfe,
	 0xff,
	0xff,
	 0xe2,
};
__fuse_t __fuse __attribute__((section (".fuse"))) = {
	.byte[0] = 0xFF,
	.byte[1] = 0x00,
	.byte[2] = 0xFE,
	.byte[3] = 0xFF,
	.byte[4] = 0xFF,
	.byte[5] = 0xE2,
};

NVM_FUSES_t fuses = {
	.FUSEBYTE0 = 0xFF,
	.FUSEBYTE1 = 0x00,
	.FUSEBYTE2 = 0xFE,
	.reserved_0x03 = 0xFF,
	.FUSEBYTE4 = 0xFF,
	.FUSEBYTE5 = 0xE2,
};

int main(void)
{
...
}

I do not redefine the fuses in my code elsewhere.

Thank you all!

Regards!
FS.

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

I do what you are doing in code and program with an ELF file, and it sets the fuses when I program with atprogram. I wrote a little GUI front end for the production staff.

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

As mojo-chan says the key thing (having embedded a .fuse section) is how you then program the AVR. It has to be ELF not HEX programming (by the time HEX is created the .fuse section is discarded). Also the tool you use has to know how to make use of a .fuse section it finds in the ELF. AFAIK there are only two programming tools that know how to use this. One is Atmel's own atprogram.exe and the other is (recent version) avrdude.exe

 

As long as you use one of those two and an ELF file that has .fuse then the programming should set the fuses at the same time as it uses .text/.data to program the flash.

 

You can use avr-objdump to check that any ELF contains .fuse (and possibly .lock) and also to dump the actual bytes the section contains.

 

BTW I tried your example:

D:\atmel_avr\avr8-gnu-toolchain\bin>type avr.c
#include <avr/io.h>

FUSES =
{
         0xff,
        0x00,
        0xfe,
         0xff,
        0xff,
         0xe2,
};

int main(void)
{
    while (1)
    {
    }
}

D:\atmel_avr\avr8-gnu-toolchain\bin>avr-gcc -mmcu=atxmega128a1u -Os avr.c -o avr.elf

D:\atmel_avr\avr8-gnu-toolchain\bin>avr-objdump -s -j .fuse avr.elf

avr.elf:     file format elf32-avr

Contents of section .fuse:
 820000 ff00feff ffe2                        ......

So, yes, that seems to have succeeded in creating the .fuse section with the right contents.

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

I managed to program the fuses and lock bits, here there are two comments that might help someone elsewhere:

  • The user must go to Production file at Device programming select the .elf file and mark Flash, Fuses and Lock Bits. You should do not go to Memories as I was used to go to.
  • after some tries I realized that not using the defines, or in another words using the full command i.e. unsigned char __lock __attribute__((section (".lock"))), makes my compiler better understand that it should create an .elf with a dedicated Lockbit or Fuse partition. -- I don't really know why, but at the begging the boxes at Production File could not be marked, it changed when I wrote the complete command.

 

Regards!
FS.

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

F Schneider wrote:
not using the defines, or in another words using the full command i.e. unsigned char __lock __attribute__((section (".lock"))), makes my compiler better understand that it should create an .elf with a dedicated Lockbit or Fuse partition. -- I don't really know why
Mystery to me too. If you -save-temps and look at the .i file you will find that the fuse.h and lock.h macros pretty much expand out to exactly the same thing anyway! Here's the FUSE= one for example:

# 2 "avr.c" 2

NVM_FUSES_t __fuse __attribute__((__used__, __section__ (".fuse"))) =
{
  0xff,
 0x00,
 0xfe,
  0xff,
 0xff,
  0xe2,
};

That's what the compiler actually sees when the source says:

FUSES =
{
         0xff,
        0x00,
        0xfe,
         0xff,
        0xff,
         0xe2,
};

Haven't tried LOCKBITS = but I'd be very surprised if it were radically different. -save-temps will tell you.