ATtiny1614 Fuse settings + Avrdude

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

Hi!

 

I'm using a ATtiny1614 and trying to setup the fuses.

For while i'm programming the .hex file with avrdude and an Arduino (ElTangas UPDI Programmer) but I don't know how can I setup the fuses since I'm generating the hex file from AS7 and programming externally with avrdude.

 

Can someone help me?

 

Thanks

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

bp94 wrote:
since I'm generating the hex file from AS7
In which case you may want to read this page in the manual:

 

https://www.nongnu.org/avr-libc/user-manual/group__avr__fuse.html

 

However to use this requires that you are using "ELF programming" not "HEX programming" (as it relies on a .fuse section that is embedded in the ELF).

 

Personally I'd tend to treat (during development) fuses as a "fire once and forget". You only need to work out once what you need, have one programming session during which you program the fuses then never go near them again.

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

Tell us what you want to do, or post the fuse settings you think you want to set and someone here will guide you to the correct fuse settings.

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

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

So first I have to flash a .elf with this code?

 

FUSES = {
    .WDTCFG     = WDT_WINDOW_OFF_gc | WDT_WINDOW_8KCLK_gc,  // WDT = OFF
    .BODCFG     = LVL_BODLEVEL7_gc | SAMPFREQ_1KHZ_gc | ACTIVE_ENABLED_gc | SLEEP_SAMPLED_gc,  // BOD level = 4.3V
    .OSCCFG     = FREQSEL_20MHZ_gc,
    //  .TCD0CFG    =
    //  .SYSCFG0    =
    //  .SYSCFG1    =
    //  .APPEND     =
    //  .BOOTEND    =
};

int main(void)
{
    
}

 

 

And after that I can flash my program .hex normally?

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

This is my fuse settings.

 

FUSES = {
    .WDTCFG     = WDT_WINDOW_OFF_gc | WDT_WINDOW_8KCLK_gc,  // WDT = OFF
    .BODCFG     = LVL_BODLEVEL7_gc | SAMPFREQ_1KHZ_gc | ACTIVE_ENABLED_gc | SLEEP_SAMPLED_gc,  // BOD level = 4.3V
    .OSCCFG     = FREQSEL_20MHZ_gc,
    //  .TCD0CFG    =
    //  .SYSCFG0    =
    //  .SYSCFG1    =
    //  .APPEND     =
    //  .BOOTEND    =
};

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

And after that I can flash my program .hex normally?

You seem confused. Try following Jim's advice in #3

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

I want to activate the BOD and WDT.

But I don't know how to send it to the ATtiny

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

As a general rule, programming is either a single step process using the .elf file, or a two step process using the .hex file and following that with setting the fuses.

Which method you use will depend on the tools you use.

I'm not an avrdude expert so others will need to jump in, but this method uses the two step method, although it can be all on one command line, using the .hex file and fuse settings.

The other way is to use atprogram and one of several Atmel programmers with the .elf file method. 

 

Hope that helps.

 

Jim

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

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

Well you should be able to do it with some -U's on the avrdude command line. It accepts things like "-U hfuse:w:0xNN:m" however the "tricky bit" for these new AVRs will be knowing what replaces "lfuse","hfuse","efuse" as presumably they aren't called that any more.

 

EDIT: Oh I see from:

 

https://github.com/facchinm/avrdude/blob/master/avrdude.conf.in#L15248

 

that apparently these "8x" parts now just call the fuse bytes "fuse0", "fuse1", "fuse2" and so on.

 

You are going to need a fairly recent avrdude (or more specifically avrdude.conf) so it "knows" about these new chips.

Last Edited: Mon. Jul 1, 2019 - 03:02 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok

I can use the .elf file on avrdude. I just don't know how can I set the fuses in code, because the device I'm using (Attiny1614) doesn't accept this format (lfuse, hfuse, efuse -  https://www.nongnu.org/avr-libc/user-manual/group__avr__fuse.html)

 

So I tried this way:

 

FUSES = {
    .WDTCFG     = WDT_WINDOW_OFF_gc | WDT_WINDOW_8KCLK_gc,  // WDT = OFF
    .BODCFG     = LVL_BODLEVEL7_gc | SAMPFREQ_1KHZ_gc | ACTIVE_ENABLED_gc | SLEEP_SAMPLED_gc,  // BOD level = 4.3V
    .OSCCFG     = FREQSEL_20MHZ_gc,
    //  .TCD0CFG    =
    //  .SYSCFG0    =
    //  .SYSCFG1    =
    //  .APPEND     =
    //  .BOOTEND    =
};

 

instead of this

 

FUSES =

{

.low = LFUSE_DEFAULT,

.high = (FUSE_BOOTSZ0 & FUSE_BOOTSZ1 & FUSE_EESAVE & FUSE_SPIEN & FUSE_JTAGEN),

.extended = EFUSE_DEFAULT,

};

 

But it seems not work.

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

You have to set _all_ the fuses or you will brick the chip.

You are lucky you weren't able to program the fuses yet. Set the unused fuses to default values.

 

These are the default values, so change what you need to change and write the others to default values, especially SYSCFG0.

FUSES = {
	.WDTCFG = 0x00,			/* Watchdog Configuration */
	.BODCFG = 0x00,			/* BOD Configuration */
	.OSCCFG = 0x02,			/* Oscillator Configuration */
	.reserved_0x03 = 0xFF,
	.TCD0CFG = 0x00,
	.SYSCFG0 = 0xF6,		/* System Configuration 0 */
	.SYSCFG1 = 0x07,		/* System Configuration 1 */
	.APPEND = 0x00,			/* Application Code Section End */
	.BOOTEND = 0x00			/* Boot Section End */
};

 

If you don't to this, all "commented out" fuses will be set to zero with very bad results. They will not be preserved.

Well, ok, those that default to zero may be commented out.

Last Edited: Mon. Jul 1, 2019 - 03:22 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Look at the device header...

 

/* ========== Fuses ========== */
#define FUSE_MEMORY_SIZE 9

/* Fuse Byte 0 (WDTCFG) */
#define FUSE_PERIOD0  (unsigned char)~_BV(0)  /* Watchdog Timeout Period Bit 0 */
#define FUSE_PERIOD1  (unsigned char)~_BV(1)  /* Watchdog Timeout Period Bit 1 */
#define FUSE_PERIOD2  (unsigned char)~_BV(2)  /* Watchdog Timeout Period Bit 2 */
#define FUSE_PERIOD3  (unsigned char)~_BV(3)  /* Watchdog Timeout Period Bit 3 */
#define FUSE_WINDOW0  (unsigned char)~_BV(4)  /* Watchdog Window Timeout Period Bit 0 */
#define FUSE_WINDOW1  (unsigned char)~_BV(5)  /* Watchdog Window Timeout Period Bit 1 */
#define FUSE_WINDOW2  (unsigned char)~_BV(6)  /* Watchdog Window Timeout Period Bit 2 */
#define FUSE_WINDOW3  (unsigned char)~_BV(7)  /* Watchdog Window Timeout Period Bit 3 */
#define FUSE0_DEFAULT  (0x0)
#define FUSE_WDTCFG_DEFAULT  (0x0)

/* Fuse Byte 1 (BODCFG) */
#define FUSE_SLEEP0  (unsigned char)~_BV(0)  /* BOD Operation in Sleep Mode Bit 0 */
#define FUSE_SLEEP1  (unsigned char)~_BV(1)  /* BOD Operation in Sleep Mode Bit 1 */
#define FUSE_ACTIVE0  (unsigned char)~_BV(2)  /* BOD Operation in Active Mode Bit 0 */
#define FUSE_ACTIVE1  (unsigned char)~_BV(3)  /* BOD Operation in Active Mode Bit 1 */
#define FUSE_SAMPFREQ  (unsigned char)~_BV(4)  /* BOD Sample Frequency */
#define FUSE_LVL0  (unsigned char)~_BV(5)  /* BOD Level Bit 0 */
#define FUSE_LVL1  (unsigned char)~_BV(6)  /* BOD Level Bit 1 */
#define FUSE_LVL2  (unsigned char)~_BV(7)  /* BOD Level Bit 2 */
#define FUSE1_DEFAULT  (0x0)
#define FUSE_BODCFG_DEFAULT  (0x0)

/* Fuse Byte 2 (OSCCFG) */
#define FUSE_FREQSEL0  (unsigned char)~_BV(0)  /* Frequency Select Bit 0 */
#define FUSE_FREQSEL1  (unsigned char)~_BV(1)  /* Frequency Select Bit 1 */
#define FUSE_OSCLOCK  (unsigned char)~_BV(7)  /* Oscillator Lock */
#define FUSE2_DEFAULT  (0x2)
#define FUSE_OSCCFG_DEFAULT  (0x2)

/* Fuse Byte 3 Reserved */

/* Fuse Byte 4 (TCD0CFG) */
#define FUSE_CMPA  (unsigned char)~_BV(0)  /* Compare A Default Output Value */
#define FUSE_CMPB  (unsigned char)~_BV(1)  /* Compare B Default Output Value */
#define FUSE_CMPC  (unsigned char)~_BV(2)  /* Compare C Default Output Value */
#define FUSE_CMPD  (unsigned char)~_BV(3)  /* Compare D Default Output Value */
#define FUSE_CMPAEN  (unsigned char)~_BV(4)  /* Compare A Output Enable */
#define FUSE_CMPBEN  (unsigned char)~_BV(5)  /* Compare B Output Enable */
#define FUSE_CMPCEN  (unsigned char)~_BV(6)  /* Compare C Output Enable */
#define FUSE_CMPDEN  (unsigned char)~_BV(7)  /* Compare D Output Enable */
#define FUSE4_DEFAULT  (0x0)
#define FUSE_TCD0CFG_DEFAULT  (0x0)

/* Fuse Byte 5 (SYSCFG0) */
#define FUSE_EESAVE  (unsigned char)~_BV(0)  /* EEPROM Save */
#define FUSE_RSTPINCFG0  (unsigned char)~_BV(2)  /* Reset Pin Configuration Bit 0 */
#define FUSE_RSTPINCFG1  (unsigned char)~_BV(3)  /* Reset Pin Configuration Bit 1 */
#define FUSE_CRCSRC0  (unsigned char)~_BV(6)  /* CRC Source Bit 0 */
#define FUSE_CRCSRC1  (unsigned char)~_BV(7)  /* CRC Source Bit 1 */
#define FUSE5_DEFAULT  (0xc4)
#define FUSE_SYSCFG0_DEFAULT  (0xc4)

/* Fuse Byte 6 (SYSCFG1) */
#define FUSE_SUT0  (unsigned char)~_BV(0)  /* Startup Time Bit 0 */
#define FUSE_SUT1  (unsigned char)~_BV(1)  /* Startup Time Bit 1 */
#define FUSE_SUT2  (unsigned char)~_BV(2)  /* Startup Time Bit 2 */
#define FUSE6_DEFAULT  (0x7)
#define FUSE_SYSCFG1_DEFAULT  (0x7)

/* Fuse Byte 7 (APPEND) */
#define FUSE7_DEFAULT  (0x0)
#define FUSE_APPEND_DEFAULT  (0x0)

/* Fuse Byte 8 (BOOTEND) */
#define FUSE8_DEFAULT  (0x0)
#define FUSE_BOOTEND_DEFAULT  (0x0)

So like avrdude it seems the fuses no longer have "names" but are just fuse0, fuse1 and so on. In fact you can see that in fuse.h:

#if FUSE_MEMORY_SIZE > 3

typedef struct
{
    unsigned char byte[FUSE_MEMORY_SIZE];
} __fuse_t;

So the FUSES= section is going to be something like:

FUSES = {
    .byte[0] = FUSE_WDTCFG_DEFAULT,
    .byte[1] = FUSE_LVL2 | FUSE_LVL1 | FUSE_LVL0 | FUSE_ACTIVE0 | FUSE_SLEEP1
    etc.
}

 

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

El Tangas wrote:

FUSES = {
	.WDTCFG = 0x00,			/* Watchdog Configuration */
	.BODCFG = 0x00,			/* BOD Configuration */
	.OSCCFG = 0x02,			/* Oscillator Configuration */
	.reserved_0x03 = 0xFF,
	.TCD0CFG = 0x00,
	.SYSCFG0 = 0xF6,		/* System Configuration 0 */
	.SYSCFG1 = 0x07,		/* System Configuration 1 */
	.APPEND = 0x00,			/* Application Code Section End */
	.BOOTEND = 0x00			/* Boot Section End */
};

Where are you getting those field names? I don't see them in the device header? As far as I can see the fields (when >3 fuses) are just .byte[0]=, .byte[1]= and so on ??

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

They are somewhere else in the header:

 

/*
--------------------------------------------------------------------------
FUSE - Fuses
--------------------------------------------------------------------------
*/

/* Fuses */
typedef struct FUSE_struct
{
    register8_t WDTCFG;  /* Watchdog Configuration */
    register8_t BODCFG;  /* BOD Configuration */
    register8_t OSCCFG;  /* Oscillator Configuration */
    register8_t reserved_0x03;
    register8_t TCD0CFG;  /* TCD0 Configuration */
    register8_t SYSCFG0;  /* System Configuration 0 */
    register8_t SYSCFG1;  /* System Configuration 1 */
    register8_t APPEND;  /* Application Code Section End */
    register8_t BOOTEND;  /* Boot Section End */
} FUSE_t;

 

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

Ah I see. I was misreading:

#if !defined(FUSES)
  #if defined(__AVR_XMEGA__)
    #define FUSES NVM_FUSES_t __fuse FUSEMEM
  #else
    #define FUSES __fuse_t __fuse FUSEMEM
  #endif
#endif

For tiny1614 "__AVR_XMEGA__" is in fact true. Therefore the fuses are defined in terms of NVM_FUSES_t and not just __fuse_t as I thought. __fuse_t is the thing that does:

#if FUSE_MEMORY_SIZE > 3

typedef struct
{
    unsigned char byte[FUSE_MEMORY_SIZE];
} __fuse_t;

But, as you say, it actually uses:

/* Fuses */
typedef struct FUSE_struct
{
    register8_t WDTCFG;  /* Watchdog Configuration */
    register8_t BODCFG;  /* BOD Configuration */
    register8_t OSCCFG;  /* Oscillator Configuration */
    register8_t reserved_0x03;
    register8_t TCD0CFG;  /* TCD0 Configuration */
    register8_t SYSCFG0;  /* System Configuration 0 */
    register8_t SYSCFG1;  /* System Configuration 1 */
    register8_t APPEND;  /* Application Code Section End */
    register8_t BOOTEND;  /* Boot Section End */
} FUSE_t;


/* avr-libc typedef for avr/fuse.h */
typedef FUSE_t NVM_FUSES_t;

to define NVM_FUSES_t because it's really an Xmega.

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

clawson wrote:
(...) because it's really an Xmega.

 

Yes, exactly, one must keep that in mind when navigating the headers.

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

I've set up according you wrote:

 

FUSES = {
    .WDTCFG = 0x00,            /* Watchdog Configuration */
    .BODCFG = 0xE5,            /* BOD Configuration */
    .OSCCFG = 0x02,            /* Oscillator Configuration */
    .reserved_0x03 = 0xFF,
    .TCD0CFG = 0x00,
    .SYSCFG0 = 0xF6,        /* System Configuration 0 */
    .SYSCFG1 = 0x07,        /* System Configuration 1 */
    .APPEND = 0x00,            /* Application Code Section End */
    .BOOTEND = 0x00            /* Boot Section End */
};

 

int main(void)

{

     return 0;

}

 

Generated the .elf file and using avrdude flashed the ATtiny1614

 

Are these the correct procedures?

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

Yes, but you should use the macros instead of hardcoded hex values. Then you need to extract the fuses from the elf file.

I add this to the "post-build events" on AS7:

 

"$(ToolchainDir)"\avr-objcopy.exe -O ihex -R .text -R .eeprom -R .lock -R .signature -R .user_signatures --change-section-lma .fuse=0 "$(OutputFileName).elf" "$(OutputFileName)_fuses.hex"

This will create a filename_fuses.hex file in the AS7 output directory, containing the fuses.

 

Then write the fuses with avrdude, using the -U fuses:w:filename_fuses.hex:i command.

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

I have been using the attiny1614 with fuse settings inside the code, using Atmel Studio to generate the .elf file which i then use  the Atmel Studio command prompt to program the boards at work through a batch file. I test quick code changes through AS7 programing though.

I thought AVRdude has not been updated with the Attiny1614, but i have not checked in awhile. Atmel studio command prompt works great, but (probably do to user error) i can only get the batch/.cmd files to work if they are directly located  on C: drive main in Windows 7-10. If i try to dive through folders for the batch file it is as if AS command prompt acts like Windows regular command prompt and i cannot program my target device.

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>

// Set fuses:
FUSES =
{
    .BODCFG    = ACTIVE_ENABLED_gc | LVL_BODLEVEL2_gc,// 2.6v BOD, VLM at 3.3 for battery monitor and chip shut down
    //.BODCFG    = ACTIVE_ENABLED_gc | LVL_BODLEVEL3_gc,//2.95v BOD, vlm@ +5% = 3.0975V
    .OSCCFG    = FREQSEL_16MHZ_gc,
    .SYSCFG0	= RSTPINCFG_UPDI_gc | CRCSRC_NOCRC_gc,
    .SYSCFG1	= SUT_64MS_gc,
    //.TCD0CFG	= 0x00,
    //.WDTCFG     = 0x00,
    //.APPEND     = 0x00,
    //.BOOTEND	= 0x00,
};

 

~William

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

If you browse the iotn1614.h file it will give you 5800 lines of of defines/commands you will use for 'C' code programming.

This header(along with many others) should be installed along with AS7 and are in folders located somewhere in your install folder, also available online.

This in an invaluable tool to help along with the data sheet.

~William

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

vertamps wrote:
I thought AVRdude has not been updated with the Attiny1614, but i have not checked in awhile.

 

Well, the secret avrdude build used by the Arduino IDE has been updated (windows build with extra stuff, all that matters is avrdude.exe and avrdude.conf): http://downloads.arduino.cc/tool...

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

vertamps wrote:
I thought AVRdude has not been updated with the Attiny1614, but i have not checked in awhile.
Added in '18 though the UPDI effort began in '17.

http://svn.savannah.gnu.org/viewvc/avrdude/trunk/avrdude/ChangeLog-2018?revision=1427&view=markup

...

 

2018-01-10 Joerg Wunsch <j.gnu@uriah.heep.sax.de>

 

Submitted by Jan Egil Ruud <janegil.ruud@microchip.com>

...

(ATtiny1614,...

...

 

"Dare to be naïve." - Buckminster Fuller